edit

Username + Password (Basic) Auth

The Authorization: Basic ... header can be used to send username and password credentials for authentication.

This page will show you how to use this type of authentication in your web app.

Note

Sending and storing passwords should be avoided wherever possible. Use tokens or sessions persistance to prevent the need for sending the password in every request.

Password Authenticatable

Start by conforming your user model to the PasswordAuthenticatable protocol.

import AuthProvider

extension User: PasswordAuthenticatable { }

Custom

If your user conforms to Model, all of the required methods will be implemented automatically. However, you can implement them if you want to do something custom.

extension User: PasswordAuthenticatable {
    /// Return the user matching the supplied
    /// username and password
    static func authenticate(_: Password) throws -> Self {
        // something custom
    }

    /// The entity's hashed password used for
    /// validating against Password credentials
    /// with a PasswordVerifier
    var hashedPassword: String? {
        // something custom
    }

    /// The key under which the user's username,
    /// email, or other identifing value is stored.
    static var usernameKey: String {
        // something custom
    }

    /// The key under which the user's password
    /// is stored.
    static var passwordKey: String {
        // something custom
    }

    /// Optional password verifier to use when
    /// comparing plaintext passwords from the 
    /// Authorization header to hashed passwords
    /// in the database.
    static var passwordVerifier: PasswordVerifier? {
        // some hasher
    }
}

Middleware

Once your model conforms to the PasswordAuthenticatable protocol, you can create the middleware.

import Vapor
import AuthProvider

let drop = try Droplet()

drop.middleware += [
    PasswordAuthenticationMiddleware(User.self)
]

try drop.run()

All routes on this Droplet will now be protected by the password middleware.

Seealso

If you only want to require authentication for certain routes, look at our Route Group section in the routing docs.

Call req.user.authenticated(User.self) to get access to the authenticated user.

Request

Now we can make a request to our Vapor app.

GET /me HTTP/1.1
Authorization: Basic dmFwb3I6Zm9v 

Note

dmFwb3I6Zm9v is "vapor:foo" base64 encoded where "vapor" is the username and "foo" is the password. This is the format of Basic authorization headers.

And we should get a response like.

HTTP/1.1 200 OK
Content-Type: text/plain

Vapor