Username & Password
This recipe will show you how to register users, save hashed and salted passwords in a database and issue JWTs that the frontend can use for subsequent requests.
Looking for complete code samples? Check the ready made code section!
Ingredients
- Bcrypt library for hashing passwords
- JWT library for generating JSON web tokens
- Ability to send email from your server (for email verification)
Outputs
Screens
Name | Path | Description |
---|---|---|
Register | /register | Displays the registration form and sends data to the POST /users endpoint |
Verify | /verify?token={token} | Handles email verification links, sending data to POST /auth/verify |
Login | /login | Displays the login form and sends data to the POST /auth/login endpoint |
Dashboard | / | Only accessible if the user has a valid JWT issued. Fetches data from GET /me |
Endpoints
Method | Path | Description |
---|---|---|
POST | /users | Register a new user |
POST | /auth/verify | Verifies a user's email address |
POST | /auth/token | Validates the email/password and returns a JWT |
GET | /me | Returns the current user's details, only if logged in |
Tables
Method
Registration Screen
The registration screen allows users to create accounts by specifying their email and password. It will trigger an email to be sent for verification purposes via the POST /users
endpoint.
Logic
Registration Endpoint
The POST /users
endpoint is where user accounts will be registered. It accepts a body that should contain all user information necessary to create an account, including the email and password.
Request Body
The request body can contain as few or as many fields as required for your use case. You may wish to omit the first and last names, for example.
{
"meta": {
"verificationURL": "http://localhost:3001/verify"
},
"data": {
"type": "users",
"attributes": {
"firstName": "Fred",
"lastName": "Smith",
"email": "fred@codecookbook.io",
"password": "MyS3cureP@assword#"
}
}
}
Logic
- Ensure all provided fields are valid (including password requirements)
- Hash and salt the provided password
- Save the information to the User database table
- Return the newly created user information
Response Body
{
"data": {
"type": "users",
"attributes": {
"id": 1234,
"firstName": "Fred",
"lastName": "Smith",
"email": "fred@codecookbook.io",
"createdAt": "2023-04-12T20:07:22.115Z",
"updatedAt": "2023-04-12T20:07:22.115Z"
}
}
}
Verification Screen
The verification screen is used to verify a user's email address. The POST /users
endpoint includes a link to this page when sending the verification email. The screen accepts a token in the querystring and submits the data to the POST /auth/verify
endpoint in order complete verification.
Logic
Token Endpoint
The POST /auth/token
endpoint accepts the user's credentials and returns a JSON web token (JWT) which should be stored by the client for subsequent requests.
Request Body
{
"data": {
"type: "credentials",
"attributes": {
"provider": "password",
"email": "fred@codecookbook.io",
"password": "MyS3cureP@assword#"
}
}
}
Logic
- Look up the user in the database based on the
email
field
a. Check the user exists
b. Use the bcrypt library to compare the provided password to the hashed password saved in the database - Generate a JWT, providing the user's ID as the
sub
field - Return the JWT to the client along with the user's information
Response Headers
# The Set-Cookie header contains the issued JWT as a HTTP-only cookie
Set-Cookie: access_token=dXNlcm5hbWU6cGFzc3dvcmQ...; HttpOnly
Response Body
{
"data": {
"type": "sessions",
"attributes": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
}
Protected Endpoints
In this example we will create an endpoint called GET /users/:id
which will return the specified user's details, but only if a valid JWT is provided and the sub
field matches the user ID requested. In other words, a user shouldn't be able to view another user's details.
Request Headers
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Logic
- Verify the
Authorization
header has been provided - Use the JWT library to validate the provided token
- Get the user based on the
sub
property extracted from the token (the user ID) - Throw an unauthorized exception if any of the above fails
Ready-Made Code
Download this recipe as a complete application!
Download Code