Skip to content

Persisting Auth

Persisting authentication means that a user does not need to provide their credentials with every request. This is useful for web apps where a user should only have to log in once.


For APIs, it's recommended that the user send a token with every request. See Getting Started for an example about Token auth.


Sessions are built into Vapor by default and are an easy way to persist users in your web app.


The first step is to conform your user model to the SessionPersistable protocol.

import AuthProvider

extension User: SessionPersistable {}

If your user is a Model, the protocol methods will be implemented automatically. However, you can implement them if you want to do something custom.

import AuthProvider
import HTTP

extension User: SessionPersistable {
    func persist(for: Request) throws {
        // something custom

    static func fetchPersisted(for: Request) throws -> Self? {
        // something custom


Now that the user is SessionPersistable, we can create our middleware.


First let's start by creating SessionsMiddleware. We'll use the MemorySessions() to get started.

let memory = MemorySessions()
let sessionsMiddleware = SessionsMiddleware(memory)


Now let's create the PersistMiddleware. This will take care of persisting our user once they've been authenticated.

let persistMiddleware = PersistMiddleware(User.self)

Since our user conforms to SessionPersistable (and thus Persistable), we can pass it into this middleware's init.


Now to create the authentication middleware of your choice. We'll use PasswordAuthenticationMiddleware which requires an Authorization: Basic ... header with the user's username and password.

let passwordMiddleware = PasswordAuthenticationMiddleware(User.self)

!!! note: User must conform to PasswordAuthenticatable to be used with this middleware. See the Password section to learn more.


Now we can create a Droplet and add all of our middleware.

import Vapor
import Sessions
import AuthProvider

let drop = try Droplet()

let authed = drop.grouped([sessionsMiddleware, persistMiddleware, passwordMiddleware])


If you only want to globally require the password middleware, checkout the Middleware Config section in the HTTP docs.


Now you can add a route to return the authenticated user.

authed.get("me") { req in
    // return the authenticated user
    return try req.auth.assertAuthenticated(User.self)


Now we can make a request to our Vapor app.

GET /me HTTP/1.1
Authorization: Basic dmFwb3I6Zm9v 


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
Set-Cookie: vapor-session=...


Notice the vapor-session in the response. This can be used in subsequent requests instead of the username and password.