Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using API-Key in Vapor

Tags:

vapor

I'm developing a simple web API with Vapor. To give more context, I'm newbie in backend development.

The consumer of the API is going to be an iOS app. Currently, I don't need the users to sign up to use the app. And I would like to keep it like that.

On the other hand, I would like to have some authentication to avoid that anyone could use the API I'm developing.

Looking for information I've found how implement authentication. But the examples I've seen are based on creating users in the backend for each user of the app. What I don't want to do. I would like to use an api-key as we do normally when we use third-party api's.

How could I have "api-key authentication" with Vapor ??

Or, should I just create an unique user/password that it's shared by all the users of the iOS app (that use the API) and then use basic or token authentication?

Thank you very much!

Carlos

like image 705
Carlos Avatar asked Nov 23 '18 23:11

Carlos


People also ask

What can someone do with your API key?

API keys can identify a project to an API and specify which resources a project may access. However, experts do not consider API keys to be secure enough on their own. This is for a few reasons: API keys can't authenticate the individual user making the request, only the project or application sending the request.

Where should I put my API keys?

Instead of embedding your API keys in your applications, store them in environment variables or in files outside of your application's source tree.


2 Answers

One way around this is to create a fake token and use either the TokenAuthenticationMiddleware or more likely a custom middleware that checks the incoming token.

However, be aware that there is nothing stopping anyone from inspecting the traffic coming from your app to view the token and then using that to access your API.

like image 167
0xTim Avatar answered Oct 16 '22 18:10

0xTim


Following Tim idea and an example from the book Server Side with Vapor (by the Raywenderlich.com Tutorial Team) I've created this custom middleware that makes the work:

final class SecretMiddleware: Middleware {

let secret: String

init(secret: String) {
    self.secret = secret
}

func respond(to request: Request, chainingTo next: Responder) throws -> Future<Response> {

    guard let bearerAuthorization = request.http.headers.bearerAuthorization else {
        throw Abort(.unauthorized, reason: "Missing token")
    }

    guard bearerAuthorization.token == secret else {
        throw Abort(.unauthorized, reason: "Wrong token")
    }

    return try next.respond(to: request)
}
}
extension SecretMiddleware: ServiceType {

static func makeService(for worker: Container) throws -> SecretMiddleware {

    let secret: String
    switch worker.environment {
    case .development:
        secret = "foo"
    default:
        guard let envSecret = Environment.get("SECRET") else {
            let reason = "No SECRET set on environment."
            throw Abort(.internalServerError, reason: reason)
        }
        secret = envSecret
    }
    return SecretMiddleware(secret: secret)
}
}
like image 41
Carlos Avatar answered Oct 16 '22 18:10

Carlos