Let’s Build User Authentication with Express, Prisma, and JWTs

bshelling
4 min readMar 25, 2022

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

Registration Frontend Form
  • 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`
/register request and response
Registration code block

User login

Frontend Login Form
  • 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”
/login request and response
Generated JWT set to accessToken cookie
Login code block

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”
/forgot-password request and response
Forgot password code block

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”
/reset-password request and response
Reset password code block

Logout

  • Clears access token when user logs out
/logout code block

Checkout the project’s repo: https://github.com/bshelling/user_authentication_pattern

--

--

bshelling

Shelling is what they call me. A forward thinker debugging life's code line by line. Creator, crossfitter, developer, engineer