Let’s Build User Authentication with Express, Prisma, and JWTs
User authentication and authorization is the crux of every application or website we use today. If you ever wanted to build this system, I will describe how.
User authentication as we know it
When we think about user authentication, we know for a user to access information within an app or site, the user needs to register, once registered they can login with access, if the user forgets their password they can request a reset and the user can logout when they’re done.
Getting Started
Each step will be accompanied by code, UI concept, the request, the response and code block.
For this build the dependencies are:
- Express (API)
- Prima (ORM)
- SQLite (Development database)
- Argon2 (Password Hashing)
- JsonWebtoken (User Authorization)
Imports and Environment settings
Starting from the top, import dependencies and declare environment variables.
User Registration
- New user enters username, email, and password
- Plain text password is hashed and new user record is stored with username/email/password
- Response: message: `${req.body.username} account has been created`
User login
- User enters username and password
- Username is passed to a database query to retrieve the user
- Password is passed to the compare plain text with hashed
- If the password is valid and login retries are < 3 retry and retryExp set to 0, jwt is signed and set to cookie, with an expiration of 8 hours. Then redirect to /dashboard
- If 3 password retries, account is locked for time period set by RETRY_TIMER variable, after time has expired the user can attempt to login
- If the user doesn’t exist — 400 error with message “Account doesn’t exist”
Forgot password
- User enters email to request a new password
- Email is passed to a database query to retrieve the user
- If the user exists — reset password hash is generate and added to the user’s record with a token expiration
- If the user doesn’t exist — 400 error with message “Account doesn’t exist”
Reset password
- User enters a new password and token is sent with request
- Reset password token is passed to a database query to retrieve the user
- If the reset expiration exists — a check is executed to see if it’s expired.
- If the token is not expired, the new password is updated on the record
- If the token is expired — response: “Reset password link has expired”
- If the token is invalid — response: “Are you trying to reset your password? Visit ${SITE}/forgot-password to reset your password”
Logout
- Clears access token when user logs out
Checkout the project’s repo: https://github.com/bshelling/user_authentication_pattern