To allow our users to stay logged in for longer periods, let's add refresh tokens to our authentication system. At the same time, we'll reduce the lifespan of our access tokens to improve security.
In our case, a refresh token will just be a random 256-bit string. It's a token, but not a JSON Web Token. It doesn't need to be a JWT because we'll store it in our database and associate it with a user server-side. No point in using stateless JWTs if we're going to store them in a database anyway.
To revoke a refresh token, we'll set a revoked_at timestamp in the database. If revoked_at is not null, the token is revoked and will be considered invalid.
token: the primary key - it's just a stringcreated_atupdated_atuser_id: foreign key that deletes the row if the user is deletedexpires_at: the timestamp when the token expiresrevoked_at: the timestamp when the token was revoked (null if not revoked)crypto/rand package (math/rand's Read function is deprecated).{
"id": "5a47789c-a617-444a-8a80-b50359247804",
"created_at": "2021-07-01T00:00:00Z",
"updated_at": "2021-07-01T00:00:00Z",
"email": "[email protected]",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
"refresh_token": "56aa826d22baab4b5ec2cea41a59ecbba03e542aedbb31d9b80326ac8ffcfa2a"
}
Look up the refresh token in the database. If it doesn't exist, or if it's expired or revoked, respond with a 401 status code. Otherwise, respond with a 200 code and this shape:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
The token field should be a newly created access token for the given user that expires in 1 hour. I wrote a GetUserFromRefreshToken SQL query.
Revoke the refresh token record in the database that matches the refresh token passed in the request header by setting the revoked_at to the current timestamp. Remember that any time you update a record, you should also be updating the updated_at timestamp.
Respond with a 204 status code. A 204 status means the request was successful but no body is returned.
Run and submit the CLI tests.