How to Implement Secure User Logout and JWT Verification in Node.js

How to Implement Secure User Logout and JWT Verification in Node.js

Steps to Ensure Secure User Logout and Verify JWT in Node.js

Ensuring user security is paramount in web development. Implementing a secure user logout process and JWT verification is crucial for maintaining a secure application. In this blog post, we'll walk you through the process of setting up secure user logout and JWT verification in a Node.js application using Express, Mongoose, and JSON Web Tokens (JWT).

1. Introduction

JSON Web Tokens (JWT) are a popular method for securely transmitting information between parties as a JSON object. In this tutorial, we'll create a secure logout process that ensures the user’s JWT is invalidated, preventing any unauthorized access.

2. Setting Up the Project

To get started, ensure you have Node.js and npm installed. Create a new project and install the necessary dependencies:

bashCopy codemkdir secure-logout-jwt
cd secure-logout-jwt
npm init -y
npm install express mongoose jsonwebtoken cookie-parser

3. Creating the User Model

First, let's create a User model using Mongoose. This model will store user information, including the refresh token.

javascriptCopy code// models/user.model.js
import mongoose from 'mongoose';

const userSchema = new mongoose.Schema({
    username: { type: String, required: true },
    password: { type: String, required: true },
    refreshToken: { type: String }
});

export const User = mongoose.model('User', userSchema);

4. Implementing JWT Verification Middleware

Next, we'll create middleware to verify the JWT. This middleware will check the validity of the token and attach the user information to the request object.

javascriptCopy code// middleware/verifyJWT.js
import jwt from 'jsonwebtoken';
import { User } from '../models/user.model.js';
import { ApiError } from '../utils/ApiError.js';
import { asyncHandler } from '../utils/asyncHandler.js';

export const verifyJWT = asyncHandler(async (req, _, next) => {
    try {
        const token = req.cookies?.accessToken || req.header("Authorization")?.replace("Bearer ", "");

        if (!token) {
            throw new ApiError(401, "Unauthorized request");
        }

        const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
        const user = await User.findById(decodedToken?._id).select("-password -refreshToken");

        if (!user) {
            throw new ApiError(401, "Invalid Access Token");
        }

        req.user = user;
        next();
    } catch (error) {
        throw new ApiError(401, error?.message || "Invalid access token");
    }
});

5. Creating the Logout Endpoint

Now, let's create the logout endpoint. This endpoint will invalidate the refresh token and clear the JWT cookies.

javascriptCopy code// controllers/auth.controller.js
import { asyncHandler } from '../utils/asyncHandler.js';
import { User } from '../models/user.model.js';
import { ApiResponse } from '../utils/ApiResponse.js';

export const logoutUser = asyncHandler(async (req, res) => {
    await User.findByIdAndUpdate(req.user._id, { $set: { refreshToken: undefined } }, { new: true });

    const options = { httpOnly: true, secure: true };

    return res
        .status(200)
        .clearCookie("accessToken", options)
        .clearCookie("refreshToken", options)
        .json(new ApiResponse(200, {}, "User logged out"));
});

6. Setting Up the Routes

Configure the routes in your Express application to include the logout route.

javascriptCopy code// routes/auth.routes.js
import express from 'express';
import { verifyJWT, logoutUser } from '../controllers/auth.controller.js';

const router = express.Router();

router.route('/logout').post(verifyJWT, logoutUser);

export default router;

7. Testing the Implementation

Start your server and test the logout functionality. Ensure the JWT tokens are invalidated and the cookies are cleared upon logout.

javascriptCopy code// server.js
import express from 'express';
import mongoose from 'mongoose';
import cookieParser from 'cookie-parser';
import authRoutes from './routes/auth.routes.js';

const app = express();
app.use(express.json());
app.use(cookieParser());

mongoose.connect('mongodb://localhost:27017/secure-logout-jwt', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

app.use('/api', authRoutes);

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

8. Conclusion

Implementing secure user logout and JWT verification in a Node.js application is crucial for maintaining a secure and robust application. By following the steps outlined in this guide, you can ensure your application handles user authentication and logout securely.

Follow For More : https://www.linkedin.com/in/akash-satpute-548b5a256/

#NodeJS #JWT #WebSecurity #UserAuthentication #ExpressJS #Mongoose

Did you find this article valuable?

Support Akash Satpute by becoming a sponsor. Any amount is appreciated!