A JSON Web Token (JWT) is a JSON object that’s defined in RFC 7519 as a safe way to represent a set of information between two parties. The token is composed of a header, a payload, and a signature. JWT is used for authentication, and they can also be used for sharing information. Most JWT are signed using a public key and a private key; therefore, it’s very difficult to tamper with these tokens.
In authentication, when the user successfully logs in using their credentials, a JSON Web Token will be returned and must be saved locally (typically in local or session storage, but cookies can also be used), instead of the traditional approach of creating a session in the server and returning a cookie.
This is a stateless authentication mechanism as the user state is never saved in server memory. The server’s protected routes will check for a valid JWT in the Authorization header, and if it is present, the user will be allowed to access protected resources. As JWTs are self-contained, all the necessary information is there, reducing the need to query the database multiple times.
Using JWT with Node.js
In this tutorial, we’ll be creating a simple Express app to manage a list of our favorite movies. There will be two types of users — admin and members. Admin will be able to create new movies, whereas members will only have read-access. This could be extended for the remainder of the CRUD functionality but for simplicity’s sake we’ll stick with just the Create action.
To get started, we’ll initialize and empty Node project and install a few dependencies:
$ npm init -y$ npm install --save express body-parser jsonwebtoken
After that we’ll spin up our express server and configure our middleware.
Next, we’ll create our pseudo user database table just in the form of an array to keep it simple. Every user will have a username, password and role. If in a production environment, make sure you hash your passwords with something like BCrypt.
Now we’ll create a request handler to handle a user login request. First we create a secret to sign the JWT token that we’ll create after a successful login. The more complex this access token is, the more secure your application will be. So try to use a complex random string for this token.
Our login route searches for a user that matches the username and password in the body of the request and if found generates a token, signs with our secret and returns it as JSON.
After starting our server, we can test by sending a POST request through Postman or any rest-client of your choosing.
After sending a POST request to our login endpoint with the corresponding user information we can see that our server is responding properly with our token. At this point, you’d want to store this in localStorage client-side.
Next we’ll create a simple route to retrieve all movies from our ‘database’.
But because our movies should only be visible to authenticated and authorized users we’ll need to create some middleware to handle the authentication.
In this middleware, we are reading the value of the Authorization header. Since the header’s value is using the Bearer schema as recommended in the JWT documentation we need to split the string by the space and grab the token value from the 1st position.
Authorization: Bearer <token>
Then we have to verify the token and once verified we attach the user to the request object and continue. After that we’ll add our new middleware to our movies endpoint and test again.
Make sure to pass the value in the Bearer <token> format as shown below.
Lastly, we can create our final endpoint to create a movie. Because only admin users can create a new movie we’ll need to verify the user role as well.
We’ll use the same middleware we just created above.
Since the authenticateJWT middleware binds the user to the request we can pull the role from the req.user object and verify if they are of the ‘admin’ type. If so, our movie is created and added to our ‘database’, otherwise, we’ll throw an error.
In this article, we have introduced you to JWT and how to implement JWT with Express. This is by no means a fully comprehensive authentication solution but this should be enough to get you up and running. For further improvements, I’d recommend having your tokens expire as in this implementation if a token were to be stolen that would allow limitless access. To do this you’ll need to create a separate JWT token, a refresh token, which can then be used to generate a new access token.
Feel free to check out the source code here and thanks for reading.