JSON Web Token (JWT) is a compact, URL-safe means of securely transmitting information between parties as a JSON object. JWT is a simple text string that can be used by the client and server to authenticate and transfer the information easily.  A Token is encoded from a payload data using a secret key. That token is passed to the client. Whenever the client sends that token along with a request, the server validates it and sends back the response. Basically, JWT allows authentication without actually storing the user information on the system itself.

 

Below is the data flow using JWT –

  1. A client sends the username and password to the server.
  2. The server validates the authentication. If the authentication is successful, the server creates a JWT token for the client and sends it to the client in response. If authentication is unsuccessful, the server will send an error to the client.
  3. From the next request, the client for making any request supplies the JWT token in request headers like this. Authorization: Bearer <jwt_token>
  4. The server upon receiving the JWT validates it and sends the successful response else error.

 

Below is the data flow diagram for the JWT Flow.

JSON Web Token (JWT)

The JWT Format –

Suppose a user tries to log in the application and on the successful authentication, the user will get a token in response. The token will look like this.

 

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRt aW4iOnRydWUsImp0aSI6IjY3NzM4Yjk2LWE2NzYtNDBlYy1hNzc3LTNhZmRjZThkYWUyNSIsImlhdCI6MTU4Mj Y5MzAyNywiZXhwIjoxNTgyNjk2NjI3fQ.NiUXgZZruVFsf8uZAveMO7NieYqbJqzTGcByHZMb5zU

 

A JWT Token mainly consists of three parts separated by (.) dots. 

  1. Header
  2. Payload
  3. Signature

 

  1. Header – The header consists of two parts, the type of token, that is JWT and the hashing algorithm that is being used such as HMAC,  SHA256 or RSA. 

 

For Example –

{

 "alg”: "HS256”,

 "typ": "JWT"

}

From the above JWT example, the header part is. 

 

      eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

 

  1. Payload – The second part of the Token is the payload. The payload contains application-specific information usually user information along with other options that may contain expiry and validity of the token.

 

{

 "username”: "user1@gmail.com”,

 "password": "user@12345"

}

From the above JWTM, the payload is – 

 

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6IjY3NzM4Yjk2L WE2NzYtNDBlYy1hNzc3LTNhZmRjZThkYWUyNSIsImlhdCI6MTU4MjY5MzAyNywiZXhwIjoxNTgyNjk2NjI3fQ

 

3 Signature –  The third part of the Token is signature. Signature is generated by combining the first two parts of the Token with a secret key. The signature is used to verify that the sender of the JWT and to ensure that the message was not changed along the way.

 

To create the signature, the Base64-encoded header and payload are taken, along with a secret, and signed with the algorithm specified in the header.

For example -, we are creating a signature for a token using the HMAC SHA256 algorithm

 

 HMACSHA256(

   base64UrlEncode(header) + “.” +

   base64UrlEncode(payload),

   secret

 )

 

From the above JWT, the signature is –

NiUXgZZruVFsf8uZAveMO7NieYqbJqzTGcByHZMb5zU 

 

Verifying the JWT –  

The server verifies the token by creating the signature again. Signature is once again generated using the header and payload from the incoming JWT, and the secret key. If the signature matches the one on the JWT, then the JWT is considered valid.

 

Suppose someone tries to generate a fake token to access the sensitive data of a website. They can easily generate the Header and Payload but without knowing the secret key, they will not be able to generate signatures.

 

Implementation of JWT in Node JS

We have seen the working of JWT and it’s structure. Now let’s implement it in the Node js.

There are many npm libraries available for implementing the JWT functionalities. We can plug them and we can get the two most important functionalities to generate JWT and validate JWT.

 

Step 1 – Creating The HTTP Server

 

Create an HTTP server with the essential routes in index.js file

 

const express = require("express");

const bodyParser = require("body-parser");

const cookieParser = require("cookie-parser");

const middleware = require("./middleware");



const { signIn, CheckValidToken } = require("./handlers");



const app = express();

app.use(bodyParser.json());

app.use(cookieParser());



app.post("/signin", signIn);

app.get("/checkValidToken", middleware.checkToken, CheckValidToken);



const server = app.listen(8000, () => {

 console.log("server is running on  port : ", 8000);

});



module.exports = {

 server

};



app.listen(8000);

 

We have imported signIn, welcome, refresh method from the handler.js file. We have declared three routes which are “/signIn”, “/welcome” and “/refresh”. 

 

Step 2  – Creating Config.js

 

I have created a config.js file. In which I have declared the secret key for JWT and it expires time.

 

module.exports = {

 secret: "shailendraSecretKey",

 jwtExpirySeconds: 30000

};

 

Step 3 – Handling Sign In – 

 

We have declared the “/signIn” route. It will take user credentials and log them. Normally we have a database for storing user information. But for simplicity, I am storing the user information inside an object in the file itself. 

 

const applicationUsers = { username: "manish", password: "mani@123" },



const JWT = require("jsonwebtoken");

const config = require("./config.js");



const applicationUsers = { username: "manish", password: "mani@123" },



export function signIn (req, res) {

 const { username, password } = req.body;

 if (username && password) {

   if(username === applicationUsers.username && password === applicationUsers.password) {

     let token = JWT.sign({username: username},

       config.secret,

       { expiresIn: '24h'

       }

     );

     res.json({

       success: true,

       message: 'Authentication successful!',

       token: token

     });

   } else {

     res.send(403).json({

       success: false,

       message: 'Incorrect username or password'

     });

   }

 } else {

   res.send(400).json({

     success: false,

     message: 'Authentication failed! Please check the request'

   });

 }

};

 

We are using jsonwebtoken npm module to generate and validate the JWT Token. Below is the code for creating a JWT token.  We are using sign() method of jsonwebtoken library. JWT.sign function takes the payload, secret and options as its arguments. The payload can be used to find out which user is the owner of the token. Options can have an expire time until which token is valid. The generated token will be a string.

 

let token = JWT.sign({username: username},

       config.secret,

       { expiresIn: '24h'

       }

     );

 

We are sending this generated token back to the client. Clients should preserve this for future requests.

 

Now, Let’s run the application, open the terminal, go to the root folder of the application and run.

 

Json Web Token

 

npm start // this will start the server, you will see the terminal like this

 

Now Let’s try the sign-in API using the CURL command from the terminal. We are using CURL as a client. When the browser (SPA) makes this request to the server, the user should store this token in the local storage.

 

Run the following command in the separate terminal.

 

curl --header "Content-Type: application/json" --request POST  --data '{"password":"mani@123", "username":"manish"}' http://localhost:8000/signin;

 

This will gives the output in the terminal like this – 

 

{

 "success":true,

 "message":"Authentication successful!",

"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1hbmlzaCIsImlhdCI6MTU4MjcwNTcxMywiZXhwIjoxNTgyNzkyMTEzfQ.7dET3__BugeOC2_HOPScO-jnF8iDf6eBvQdAjvcE4sg"

}

 

We are sending a token to the client. Clients should save this token in local storage or session storage. Clients should add this token in the header for further requests.

 

Step 4 – Create middleware.js

 

We have made a middleware that will check whether the request contains a valid token or not. 

 

let JWT = require("jsonwebtoken");

const config = require("./config.js");



let checkToken = (req, res, next) => {

 let token = req.headers["x-access-token"] || req.headers["authorization"]; // Express headers are auto converted to lowercase

 if (token.startsWith("Bearer ")) {

   // Remove Bearer from string

   token = token.slice(7, token.length);

 }



 if (token) {

   JWT.verify(token, config.secret, (err, decoded) => {

     if (err) {

       return res.json({

         success: false,

         message: "Token is not valid"

       });

     } else {

       req.decoded = decoded;

       next();

     }

   });

 } else {

   return res.json({

     success: false,

     message: "Auth token is not supplied"

   });

 }

};



module.exports = {

 checkToken: checkToken

};

 

Let make another CURL request with the token and check token is valid or not.

 

Curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im1hbmlzaCIsImlhdCI6MTU4MjcwNTcxMywiZXhwIjoxNTgyNzkyMTEzfQ.7dET3__BugeOC2_HOPScO-jnF8iDf6eBvQdAjvcE4sg' http://localhost:8000/checkValidToken

 

jwt curl

 

The output will look like this – 

 

{"success":true,"message":"Token is valid"}

 

This is how JWT integration works for authentication. We have successfully integrated it into our application.

 

I hope this article helped you to integrate JWT token in your Node Js Application.

Happy Coding.