Open In App

How to implement JWT authentication in Express app ?

Last Updated : 18 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

A JSON Web Token (JWT) is a JSON object utilized to securely transmit information between two parties over the web. Primarily employed in authentication systems, JWTs can also facilitate secure data exchange. These tokens enhance security by incorporating encryption, and for added protection, a signature can be appended. A JWT comprises a header JSON, a payload JSON, and an optional signature. Each of these components is concatenated with a period (“.”) separator.

Below is a sample example of JSON Web Token. 

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2MTU0OWIwMTIwMWUyZjMz
ZWE3NmFkZjYiLCJlbWFpbCI6InNtdHdpbmtsZTQ1MkBnbWFpbC5jb20iLCJpYXQiOjE2Mz
I5MzQ2NTgsImV4cCI6MTYzMjkzODI1OH0._oHr3REme2pjDDdRliArAeVG_HuimbdM5suTw8HI7uc

Implementation of JWT authentication: JWT is much popular for authentication and authorization via HTTP. These tokens can be used as credentials to grant permission to access server resources.

Why do we need JWT in the authentication:

Given that HTTP requests are stateless, identifying the continuity of requests poses a challenge. For instance, after a user logs in and gains certain rights, determining in subsequent requests that it’s the same user is not straightforward. This is where JSON Web Tokens (JWT) come into play.

In the initial phase, the server generates a token, incorporating configurations such as payload, signature, and expiration. Subsequently, when a client-side request includes the JWT token within the authorization header, the server decodes the token, extracts the details, and grants access accordingly. This mechanism allows for the seamless tracking of users and their permissions across multiple requests.

Let’s Create a simple server that has the functionality to login and signup:

Step 1: Initialize server & Install JWT Package.

npm init
npm install jsonwebtoken

Step 2: Create Route for Tokens:

  • We’ve brought in essential libraries – express, mongoose, and jsonwebtoken, including the User model for database interaction. Creating an Express app using express() allows server configuration.
  • Using express.json() initially helps recognize incoming requests as JSON. Two routes are set up for login and signup.
  • In the login route, we extract email and password from the request body, searching for the user in the database. If found, we verify the provided password.
  • For signup, we extract user details (name, email, password) and use the mongoose save method to register users in the database.

Finally, we have created a token with the 1-hour expiry by providing payload as user id and email because only this is sufficient to extract the user information.  The sign method accepts payload, secret jwt key, and expiry time then generates a token.

Javascript




// Importing modules
const express = require("express");
const mongoose = require("mongoose");
 
const jwt = require("jsonwebtoken");
const User = require("./userModel");
 
const app = express();
 
app.use(express.json());
 
// Handling post request
app.post("/login",
    async (req, res, next) => {
        let { email, password } = req.body;
 
        let existingUser;
        try {
            existingUser =
                await User.findOne({ email: email });
        } catch {
            const error =
                new Error(
                    "Error! Something went wrong."
                );
            return next(error);
        }
        if (!existingUser
            || existingUser.password
            != password) {
            const error =
                Error(
                    "Wrong details please check at once"
                );
            return next(error);
        }
        let token;
        try {
            //Creating jwt token
            token = jwt.sign(
                {
                    userId: existingUser.id,
                    email: existingUser.email
                },
                "secretkeyappearshere",
                { expiresIn: "1h" }
            );
        } catch (err) {
            console.log(err);
            const error =
                new Error("Error! Something went wrong.");
            return next(error);
        }
 
        res
            .status(200)
            .json({
                success: true,
                data: {
                    userId: existingUser.id,
                    email: existingUser.email,
                    token: token,
                },
            });
    });
 
// Handling post request
app.post("/signup",
    async (req, res, next) => {
        const {
            name,
            email,
            password
        } = req.body;
        const newUser =
            User({
                name,
                email,
                password,
            });
 
        try {
            await newUser.save();
        } catch {
            const error =
                new Error("Error! Something went wrong.");
            return next(error);
        }
        let token;
        try {
            token = jwt.sign(
                {
                    userId: newUser.id,
                    email: newUser.email
                },
                "secretkeyappearshere",
                { expiresIn: "1h" }
            );
        } catch (err) {
            const error =
                new Error("Error! Something went wrong.");
            return next(error);
        }
        res
            .status(201)
            .json({
                success: true,
                data: {
                    userId: newUser.id,
                    email: newUser.email,
                    token: token
                },
            });
    });
 
//Connecting to the database
mongoose
    .then(() => {
        app.listen("3000",
            () => {
                console.log("Server is listening on port 3000");
            });
    })
    .catch(
        (err) => {
            console.log("Error Occurred");
        }
    );


Output: We are testing our API with the Postman, we have provided the data for signup in the request body and finally, get our token with some other details.

Step 3: Decoding JWT Token

  • We can receive our request with a token to grant the permissions, here we are showing a simple example of how a token is being decoded.
  • The token is being sent by request header, we are extracting the token here from the authorization header we are using split function because the token remains in the form of “Bearer Token” and we only want to extract the token that’s why providing the 1 index.
  • The verify method accepts the token and jwt key and provides the decode of the token. After this, we can get the information of the user.

Javascript




app.get('/accessResource',
    (req, res) => {
        const token =
            req.headers
                .authorization.split(' ')[1];
        //Authorization: 'Bearer TOKEN'
        if (!token) {
            res.status(200)
                .json(
                    {
                        success: false,
                        message: "Error!Token was not provided."
                    }
                );
        }
        //Decoding the token
        const decodedToken =
            jwt.verify(token, "secretkeyappearshere");
        res.status(200).json(
            {
                success: true,
                data: {
                    userId: decodedToken.userId,
                    email: decodedToken.email
                }
            }
        );
    })


Output: Here we are testing the API which is responsible to accept the token, we have passed the token in the header and finally server is successful to decode the user details.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads