JWT Authentication With Node, Express, Passport, and MongoDB

A straightforward guide for a basic implementation of JWT authentication for a MERN application.

Cam Bass
4 min readNov 25, 2022

Disclaimer for this post!

JWTs are not recommended for user sessions because they have many 
security issues with their stateless nature. Many excellent blog
posts go in-depth with the problems.

This Blog post should only be used to further your understanding
of JWTs as they have their use cases and are a powerful tool when used
correctly. (Link below for great posts on the issues with JWTs)

I will be making another post in the near future with a walk-through
of a supported solution for user sessions and I will link it here when
it's ready.

Blog post on the dangers of using JWTs for user sessions:

JSON Web Tokens (JWT) are Dangerous for User Sessions — Here’s a Solution

With the warning out of the way, let’s get to this tutorial on wiring up JWTs with Node, Express, Passport, and MongoDB.

Technical Assumptions:

  1. A running MongoDB cluster that you can connect with. We will be using mongoosefor making the connection and passport local mongoose is a mongoose plugin that simplifies building username and password login with Passport.
  2. The latest versions for Node and NPM installed on your machine
  3. Postman is installed on your machine

Step 1 — Create a project

> mkdir jwt-auth-app
> cd jwt-auth-app
> npm init
> npm install --save body-parser express jwt-simple mongoose passport passport-jwt passport-local passport-local-mongoose

Step 2 — Create a user model

We will need to create a model for user creation. This should go in a models folder, in a file, called user.js — We use passport-local-mongoose to make username and password login with passport a little easier.

models/user.js

Step 3 — Create middleware

Next, we need to create a container for registering the JWT Strategy.

middleware/auth.js

Option params for the strategy:

config.js

Step 4 — Add the controller for the account routes:

This will register the route functions used to log in, register, and visit the secured profile. This is under controllers/accountController.js

Controllers/accountController.js

Step 5 — Set up app.js

You will notice within lines 21-23 the routes are being called, and the account controller module functions are being called as the third parameter to the route function.

That concludes all the necessary code to start registering, logging in, and even a profile route protected by JWT authentication. Let’s test these new routes with Postman and ensure everything is configured correctly.

Step 6 — Test the endpoints.

  1. the registering endpoint

The created record in MongoDB:

2. The Login Endpoint:

After a successful call to this endpoint, you will receive a token in the payload that can be used for the profile endpoint, for example, below —

3. Protected Profile Endpoint

Successful GET request

Unsuccessful GET request

There you have it! That is the straightforward setup I could muster for getting a JWT authentication going for a NodeJS application. There are many considerations to make when building this out further, but this is enough to get some successful requests and get started on the path to authenticating your application. Remember, JWT should not be used for user session, and I will post a follow-up with a supported route for user session authentication.

--

--

Cam Bass

Reading/Writing about Tech, Culture, Politics, Sports, and Book Reviews. I'm interested. cambass.com