JSON Web Token(JWT) Authentication API with Node.js (Part-II)

Dipak Belsare
Oct 6 · 4 min read
Image is taken from https://javascript.plainenglish.io/

Introduction

In the previous article, we discussed how JSON Web Tokens works, their advantages, their structure. In this article, we will see how to use them to handle basic authentication and authorization in Express.

This prevents unauthorized access and allows the logged-in users to access the routes as long as they have the JWT token included in the header request.

Project Setup

$ npm install --save express

3. Create a file called index.js, which will be our authentication service:

const express = require('express');const app = express();app.listen(5000, () => {=console.log('JWT Authentication service started on port: 5000');});

4. Let’s create an array of users, which we will be used to authenticate them.
For every user, there will be the role — admin or member attached to their user object. Also, remember to hash the password if you are in a production environment:

const users = [{      username: 'adminuser',      password: 'admin123',      role: 'admin'     }, {         username: 'dipak',         password: 'dipak123',         role: 'member'
}];

5. Now we can create a request handler for user login. Let’s install the jsonwebtoken module, which is used to generate and verify JWT tokens.

$ npm i --save jsonwebtoken

6. Let’s install the body-parser middleware to parse the JSON body from the HTTP request:

$ npm i --save body-parser

7. Now, let’s these modules and configure them in the Express app:

const jwt = require('jsonwebtoken');const bodyParser = require('body-parser');app.use(bodyParser.json());

8. Now we can create a request handler to handle the user login request:

const accessTokenSecret = 'youraccesstokensecret';

This is your secret to sign the JWT token. Try to use a complex random string for this token:

app.post('/login', (req, res) => {// Read username and password from request body
const { username, password } = req.body;
// Filter user from the users array by username and password
const user = users.find(u => { return u.username === username && u.password === password });
if (user) {
// Generate an access token
const accessToken = jwt.sign({ username: user.username, role: user.role }, accessTokenSecret);
res.json({accessToken});
} else {
res.send('Username or password incorrect...');
}
});

9. Run Server and Check.

Now our code is ready for the test. Now open your terminal in the project root folder, run the following command:

$ node index.js

10. Let’s use Postman or Insomnia to make an HTTP POST request to the http://localhost:5000/login endpoint with the following JSON:

{  "username": "dipak",  "password": "dipak123"}

You should get the access token as the response:

Product Service

11. With that done, let’s create a products.js file for our product's service.

We’ll start off the file by importing the required libraries and setting up the Express app:

const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const app = express();
app.use(bodyParser.json());
app.listen(5001, () => {
console.log('Products service started on port 5001');
});

12. After the configuration, to simulate a database, let’s just create an array of products:

const products = [{"name": "A green door","price": 1000,"tags": ["home", "green"]},{"name": "A red door","price": 2000,"tags": ["home", "red"]},{"name": "A 3D door","price": 3000,"tags": ["home", "color"]},{"name": "A window","price": 1500,"tags": ["home", "slide"]},];

13. Now, we can create a very simple request handler to retrieve all products from the database:

app.get('/products', (req, res) => {
res.json(products);
});

Because our products should be only visible to authenticated users. We have to create a middleware for authentication.

Before that, create the access token secret for the JWT signing, just like before:

const accessTokenSecret = 'youraccesstokensecret';

This token should be the same one used in the authentication service. Due to the fact the secret is shared between them, we can authenticate using the authentication service and then authorize the users in the product service.

At this point, let’s create the Express middleware that handles the authentication process:

const authenticateJWT = (req, res, next) => {
const authHeader = req.headers.authorization;
if (authHeader) {
const token = authHeader.split(' ')[1];
jwt.verify(token, accessTokenSecret, (err, user) => {
if (err) {
return res.sendStatus(403);
}
req.user = user;
next();
});
} else {
res.sendStatus(401);
}
};

14. We can configure this middleware in our GET request handler, like this:

app.get('/products', authenticateJWT, (req, res) => {
res.json(products);
});

15. Let’s boot up the server and test if everything’s working correctly:

$ node products.js

Now we can send a request to the http://localhost:5001/products endpoint to retrieve all the products from the database.

Make sure you change the “Authorization” header to contain the value “Bearer [JWT_TOKEN]”, as shown in the image below:

Congratulations!!! You have done it successfully.

Thanks for reading!

You can download or clone the source code of the JSON Web Token(JWT) Authentication API with Node.js from this GitHub Repository.

nonstopio

A Bespoke Engineering Studio