

# 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.

Note

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

## Sessions

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

### SessionPersistable

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
        }
    }

### Middleware

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

#### Sessions

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

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

#### Persist

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.

#### Authentication

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.

### Droplet

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])

Seealso

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

### Route

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)
    }

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

    Vapor

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