3.2 KiB
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 SessionMiddleware. 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()
drop.middleware += [
sessionsMiddleware, persistMiddleware, passwordMiddleware
]
!!! seealso If you only want to require authentication for certain routes, look at our Route Group section in the routing docs.
Route
Now you can add a route to return the authenticated user.
drop.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.