✎ Edit on GitHub

Request

The auth property on Request lets you authenticate users and also provides some convenience methods for accessing common authorization headers.

Authorization

The authorization header is a great place to send credentials from a client.

Authorization: xxxxxxxxxx

You can access the authorization header through req.auth.header. Two common patterns are basic and bearer.

Basic

Basic authorization consists of a username and password concatenated into a string and base64 encoded.

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

This is what an example header looks like. You can read more about basic auth on wikipedia.

Below is how you access this header using req.auth.

guard let credentials = req.auth.header?.basic else {
    throw Abort.badRequest
}

The basic header returns an APIKey credential.

class APIKey: Credentials {
    let id: String
    let secret: String
}

Bearer

Another common method is bearer which consists of a single API key.

Authorization: Bearer apikey123

It is accessed similarly to the basic header and returns an AccessToken credential.

class AccessToken: Credentials {
    let string: String
}

Raw

To access the raw authorization header, use req.auth.header?.header.

Credentials

Both Basic and Bearer return something that conforms to Credentials. You can always create a custom Credentials object for authentication by conforming your own class to Credentials or by manually creating an APIKey, AccessToken, or Identifier.

let key = AccessToken(string: "apikey123")

Input

You can also create credentials from form or JSON data.

guard 
    let username = req.data["username"]?.string,
    let password = req.data["password"]?.string
else {
    throw Abort.badRequest
}

let key = APIKey(id: username, secret: password)

Login

Once you have some object that conforms to Credentials, you can try to login the user.

try req.auth.login(credentials)

If this call succeeds, the user is logged in and a session has been started. They will stay logged in as long as their cookie is valid.

Authenticate

Logging in calls the authenticate method on Auth.User model you supplied to the AuthMiddleware. Make sure you add support for all the credential types you may want to use.

Note: If you used a custom Realm, it will be called instead.

Identifier

Another important credential type is the Identifier type. This is used by Vapor when fetching the User object from the vapor-auth cookie. It is also a convenient way to log a user in manually.

static func authenticate(credentials: Credentials) throws -> Auth.User {
    switch credentials {
    ...
    case let id as Identifier:
        guard let user = try User.find(id.id) else {
            throw Abort.custom(status: .badRequest, message: "Invalid identifier.")
        }

        return user
    ...
    }
}

Adding the Identifier case for Credentials is easy, just look up the user by the identifier.

let id = Identifier(id: 42)
try req.auth.login(id)

Now you can manually log users in with just their identifiers.

Ephemeral

If you just want to log the user in for a single request, disable persistance.

req.auth.login(credentials, persist: false)

Note: Supporting Identifier credentials is required for persisted authentication to work properly.

User

By default, request.auth.user() returns the authorized Auth.User. This will need to be casted to your internal User type for use.

Adding a convenience method on Request is a great way to simplify this.

extension Request {
    func user() throws -> User {
        guard let user = try auth.user() as? User else {
            throw Abort.custom(status: .badRequest, message: "Invalid user type.")
        }

        return user
    }
}

Now you can access your User type with try req.user().