vapor-docs/2.0/docs/auth/persist.md

143 lines
3.2 KiB
Markdown

# 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](getting-started.md) 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.
```swift
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.
```swift
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.
```swift
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.
```swift
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.
```swift
let passwordMiddleware = PasswordAuthenticationMiddleware(User.self)
```
!!! note:
`User` must conform to `PasswordAuthenticatable` to be used with this middleware.
See the [Password](password.md) section to learn more.
### Droplet
Now we can create a Droplet and add all of our middleware.
```swift
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](../routing/group.md) section in the routing docs.
### Route
Now you can add a route to return the authenticated user.
```swift
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.
```http
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
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.