Protect Your REST APIs using JWT.

Prathamesh More
4 min readApr 2, 2020

In this tutorial, We will learn to protect REST APIs using JSON Web Token with an example.

What is JSON Web Token aka JWT?

JSON Web Token (JWT) is way of authenticating user on internet. As name suggest it is JSON based taken. The token is signed using private secret key or public key. For example, a server could generate token which user login and provide to the client. This token could signed using user_id or email with secret key and expiration timestamp. This token payload used when client need to authenticate on server.

JWT is mostly useful for REST APIs, mobile apps, Single Page Web Apps, etc.

Software requirements

  1. Node.js — Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
  2. Express — Fast, unopinionated, minimalist web framework for Node.js
  3. jsonwebtoken —An implementation of JSON Web Tokens.
  4. bcrypt — A library to help you hash passwords.
  5. body-parser — Node.js body parsing middleware.
  6. Postman — A collaboration platform for API development.

Project setup

We will be using the Express framework for this project. Of course, you’ll need to have Node installed.

Create a directory for our project, navigate into the directory, and issue npm init to create a .json file that manages all the dependencies for our application

Install the required packages using npm command:

npm install --save express body-parser bcrypt jsonwebtoken

Import required packages and create a server

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
const PORT = 3000;app.listen(3000, () => console.log('Server running on ' + PORT));

We implement an authentication process.

So we create three routes,

  1. Users can sign up using this route.
http://localhost:3000/signup

2. Users can sign in using this route.

http://localhost:3000/signin

After signing we return JWT token to the user. Using this token user can access protected routes.

3. Users can access posts using this route.

http://localhost:3000/posts

To access posts, a user requires a JWT token.

Now create users and posts array to store users and posts.

var users = [];
var posts = [{
'title': 'This is title of post',
'description': 'This is description of post'
}];

Create the above mentioned routes to accept data from the client.

Implement Sign up a route:

app.post('/signup', (req, res, next) => {
const { username, password } = req.body;
//Check for user already exists or not
users.forEach(user => {
if (user.username == username) {
return res.status(409).json({
message: 'User already exists'
});
}
});
//Eles push new user into database or array
const user = { username, password };
//Hash password and create token
const hashedPassword = bcrypt.hash(password, 10);
users.push(user, hashedPassword);
return res.status(201).json({
message: 'User has been created'
});
});

In the above route, we are accepting username and password from req.body .

User signup

Next, we check user already exists or not. If doesn't exist, add to database or array.

Implement Sign in a route:

app.post('/signin', (req, res, next) => {
const { username, password } = req.body;
//Signin
users.forEach(user => {
if (user.username == username && bcrypt.compare(password, user.password)) {
const token = jwt.sign({
username: user.username
}, 'secretKey', { expiresIn: '1h' });
return res.status(200).json({
message: 'Signin successful',
token: token
});
}
return res.status(401).json({
message: 'Auth failed'
});
});
return res.status(401).json({
message: 'Auth failed'
});
});

Let me explain here, we are creating JWT Payload Token here.

const token = jwt.sign({
username: user.username
}, 'secretKey', { expiresIn: '1h' });
return res.status(200).json({
message: 'Signin successful',
token: token
});

We wrapping username , secret key and token expire timestamp in hours .

jwt.sign() method will return hashed token .

We return this token to the user.

User sign in

Now implement a protected route.

Post route:

app.get('/posts', (req, res, next) => {
const token = req.headers.authorization.split(' ')[1];
const decode = jwt.verify(token, 'secretKey');
req.decode = decode;
next();
}, (req, res, next) => {
return res.status(200).json(posts);
});

Here, implementing middleware to receive token from req.headers .

Now verify received token with secret key .

If it validates all token, all posts will be sent to the user.

Protected route /posts

Code

Thank you!

Happy coding :)

Feel free to contact me or a job offer.

https://pprathameshmore.github.io/

--

--

Prathamesh More

Passionate, Self-taught Full Stack Web Developer that loves designing and building modern websites, applications, and APIs.