We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Authentication With Passwords

Authentication is the process of verifying who a user is. If you don't have a secure authentication system, your back-end systems will be open to attack!

Imagine if I could make an HTTP request to the YouTube API and upload a video to your channel. YouTube's authentication system prevents this from happening by verifying that I am who I say I am.

Passwords

Passwords are a common way to authenticate users. You know how they work: When a user signs up for a new account, they choose a password. When they log in, they enter their password again. The server will then compare the password they entered with the password that was stored in the database.

There are 2 really important things to consider when storing passwords:

  1. Storing passwords in plain text is awful. If someone gets access to your database, they will be able to see all of your users' passwords. If you store passwords in plain text, you are giving away your users' passwords to anyone who gets access to your database.
  2. Password strength matters. If you allow users to choose weak passwords, they will be more likely to reuse the same password on other websites. If someone gets access to your database, they will be able to log in to your users' other accounts.

We won't be writing code to validate password strength in this course, but you get the idea: you can enforce rules in your HTTP handlers to make sure passwords are of a certain length and complexity.

Hashing

On the other hand, we will be writing code to store passwords in a way that prevents them from being read by anyone who gets access to your database. This is called hashing. Hashing is a one-way function. It takes a string as input and produces a string as output. The output string is called a hash.

We'll cover how hashing works in-depth in a later course. For now, just know that hashing is a way to store passwords in a way that prevents them from being read by anyone who gets access to your database, but still allows us to compare passwords when a user logs in.

Assignment

  1. For the password hash, we will use Argon2. To help with this, use the library argon2id, which is a convenience wrapper around Argon2.

    Download the library:

    go get github.com/alexedwards/argon2id
    

    I wrote a couple of simple unit tests to ensure the package is working as expected.

  2. {
      "password": "04234",
      "email": "lane@example.com"
    }
    

    As long as your server uses HTTPS in production, it's safe to send raw passwords in HTTP requests, because the entire request is encrypted.

    Use your internal package's HashPassword function to hash the password before storing it in the database. Do NOT return the hashed password in the response. Again, that would be a security risk.

  3. {
      "password": "04234",
      "email": "lane@example.com"
    }
    

    You'll need a new query to look up a user by their email address (you don't have access to an ID here). Once you have the user, check to see if their password matches the stored hash using your internal package. If either the user lookup or the password comparison errors, just return a 401 Unauthorized response with the message "Incorrect email or password".

    If the passwords match, return a 200 OK response and a copy of the user resource (without the password of course):

    {
      "id": "f0f87ec2-a8b5-48cc-b66a-a85ce7c7b862",
      "created_at": "2021-07-07T00:00:00Z",
      "updated_at": "2021-07-07T00:00:00Z",
      "email": "lane@example.com"
    }
    

Run and submit the CLI tests.