JSON Web Token (JWT) in node.js (Implementing using Refresh token)

Ketan Gupta
4 min readMar 20, 2021

--

JWT authentication in node.js

In this tutorial, we will see how we can implement JWT in a node js application with access tokens as well as refresh tokens. This tutorial expects that you already have a working project, the code blocks are for reference purposes and to help you understand the logic.

The node module which we will be using is jsonwebtoken

Read about JWT (what, why, when) on jwt.io

Understanding token format: A JWT token has 3 parts separated by a “ . ”. The first part is the header which specifies information like the algorithm used to generate the signature (Third part). The second is the payload which is the information we are trying to save and the third is the signature. The First 2 parts are not encrypted. They are just base64 encoded which you can easily view by decoding on an online tool.

Implementation using middleware in Express.js

npm install jsonwebtoken

MiddleWare code for an access token

const jwt = require("jsonwebtoken");
AuthenticateJWT(req, res, next){
const authHeader = req.headers['authorization']
if (authHeader == null) return
next({status:401,message:'authorization missing'})
jwt.verify(authHeader, Constant.ACCESS_TOKEN_SECRET,(err, user) =>
{
if (err) return next({status:403,message:err.message})
req.user = user;
next()
})
},

ACCESS_TOKEN_SECRET is a secret key you use to generate JWT, In the example we are saving it in constant but for security, you should use an environment variable to pass this key. below code will generate a 32 bytes secret or you can use any random secret code.

Generating secret key

require('crypto').randomBytes(32, function(err, buffer) {
var ACCESS_TOKEN_SECRET = buffer.toString('hex');
});

The API request would look like

app.get('/api/userOrders', AuthenticateJWT, (req, res) => {
// executes after authenticateToken
// ...
})

The above code was how you will authenticate the JWT, now we will see how to generate the JWT for access and refresh. use the below function to generate JWT after authenticating your user from your database. it will create 2 tokens one is an access token (expires in 5 minutes) and the other is a refresh token (expires in 6 hours).

Generating access tokens

//payload can be userID, email or other user detailsfunction generateAccessToken(payload, ip_address) {return new Promise(function (resolve, reject) {var tokens = {};//generating acess token
tokens.accessToken = jwt.sign(payload, Constant.ACCESS_TOKEN_SECRET, { expiresIn: '5m' });
//generating refresh token
tokens.refreshToken = jwt.sign(payload, Constant.ACCESS_TOKEN_SECRET, { expiresIn: '6h' });
resolve(tokens);})};

We keep a short expiry time for an access token (JWT) that has user data to make it more secure but we do not expect users to sign in every 5 minutes. So we use refresh token for this. Every time your access token expires the application can use a refresh token to verify the user and issue a new access token.

Client-Side Token Handling

When the client receives the token, they often want to store it for gathering user information in future requests. The most popular manner for storing auth tokens are cookies and localStorage.

Why Refresh token?

Refresh tokens help in getting new access tokens without asking users to sign in again. It is handled by the application itself. you provide your Client-Side app with two different tokens, one is an access token and the other is a refresh token.

Also Read: 10 JavaScript Tricks Every Developer Should Know

JSON web token has a drawback:

you can’t Revoke access of a user till he has access and refresh token with him. So to tackle this we save the refresh token in a temporary location like a variable (map, array, etc) or Redis. every time users need a new token, match your refresh token with one in your Redis and authenticate the token with JWT as we have done for the access token. now for the revoking access you can just delete that token from your Redis.

Saving refresh token

var refreshTokens={};
//here userID is saved in payload of refresh token
refreshTokens[userId] = refreshToken;

Authenticate refresh token and issue new tokens

//decode the JWT Token 
var decoded = jwt.decode(JWTRefreshToken);
//check in temp location
if(refreshTokens[decoded.userid] === JWTRefreshToken)
// verify refresh token using jwt "AuthenticateJWT" function mentioned above and generate new access and refresh token for further use.

Here Client-Side application can check if the access token is expired and using refresh token can ask for new access and refresh token. without letting the user know about this. This way users can sign in once and use the application seamlessly. This also allows an administrator to block certain users by deleting their refresh token

var decoded = jwt.decode(JWTRefreshToken);
delete refreshTokens[decoded.userid];

--

--

Ketan Gupta
Ketan Gupta

Written by Ketan Gupta

Techie exploring Life. Providing fresh perspectives and thought-provoking insights. Follow for more.