Vapor 4 Authentication: Getting Started

In this Vapor 4 tutorial, you’ll learn how to implement user authentication for your app using both bearer tokens and basic authentication headers. By Natan Rolnik.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Adding the Login Endpoint

So far, users can sign up but cannot log in, so the server is only doing half its job. But don’t worry: Part of the code you added in the previous section makes dealing with login requests much easier.

Implementing the Login Route

Because User conforms to ModelAuthenticatable, you can use the User basic authentication middleware that Vapor provides out of the box.

Begin by adding the route in the boot(routes:) method of UserController:

let passwordProtected = 
  usersRoute.grouped(User.authenticator())
passwordProtected.post("login", use: login)

This is similar to the /users/me endpoint, but instead of using the Token authenticator, or bearer, it uses the User basic authenticator. Now, scroll down to the login(req:) method, delete the thrown error and add the code below:

// 1
let user = try req.auth.require(User.self)
// 2
let token = try user.createToken(source: .login)

return token
  .save(on: req.db)
  // 3
  .flatMapThrowing {
    NewSession(token: token.value, user: try user.asPublic())
}

Step-by-step, this is what you’re doing:

  1. Similarly to the me function, you get the user from the request authentication cache. Although the authentication mechanism is different, the approach is the same. Vapor works behind the curtains to authenticate and provide the user.
  2. Using the same createToken(source:) on user, you generate a new token, this time passing SessionSource.login. You save the new token to the database.
  3. Once you save the token, you wrap the token’s value and the user in a NewSession and return it in the response.

You’re now ready to test the /users/login endpoint.

Build and run one last time, then open the API file and send the (3) Login request. You should see a response similar to what you got from the (1) Sign up request, but with a new token, fresh from the oven:

{
  "token": "5/2BdXtsAZaLBPOCKCDgow==",
  "user": {
    "username": "NatanTheChef",
    "id": "138191B9-445D-442D-9F70-B858081A661B",
    "updated_at": "2020-03-07T19:40:54Z",
    "created_at": "2020-03-07T19:40:54Z"
  }
}
Note: If you changed the username or password when you signed up, select the Authorization tab, then Basic Auth and insert the username and password you used to sign up.

Congratulations! You’re ready to implement user authentication for your app using both bearer tokens and basic authentication headers.

Where to Go From Here?

Download the final project using the Download Materials button at the top or bottom of the page. Here are a few challenges you could try to tackle going forward:

  • Make a logout function that invalidates, revokes or deletes a token.
  • Add methods allowing users to reset their password. One way to do this is by creating a ResetPasswordToken Model which has an expiration date, an identifier and is linked to a user. Then send this unique link via email.
  • Allow logging in with Magic Links sent via email.
  • If you want a challenge, try to implement authorization in DinnerController.swift, making sure that only a host can invite users to a Dinner, and that only the invitees and the host can fetch a dinner’s information.

If you work with Amazon Web Services, take a look at my other tutorial SMS user authentication with Vapor and AWS

We hope you enjoyed this tutorial. If you have any questions or comments, feel free to join in the forum discussion below!