Back to Courses

World's Best MERN Stack Course

#30: JWT Token Verification Middleware + Creating Route to Get User Data from DB

Welcome, into the world of secure authentication with our latest tutorial! Learn how to implement JWT token verification middleware to enhance the security of your app. Plus, discover the step-by-step process of creating a route to effortlessly retrieve user data from the database.

We need to create the auth-middleware, which serves to verify the JWT.

The verification process involves a straightforward comparison with the secret key, using the actual token sent from the frontend.

Initially, let's establish the route for users. This enables the frontend to retrieve user details upon successful verification of the JWT token.

// *----------------------
//* express.Router
// *----------------------

//? In Express.js, express.Router() is a mini Express application without all the server configurations but with the ability to define routes, middleware, and even have its own set of route handlers. It allows you to modularize your routes and middleware to keep your code organized and maintainable.
//* https://expressjs.com/en/guide/routing.html
//? Use the express.Router class to create modular, mountable route handlers. A Router instance is a complete middleware and routing system; for this reason, it is often referred to as a β€œmini-app”.

const express = require("express");
const router = express.Router();
const authControllers = require("../controllers/auth-controller");
const signupSchema = require("../validators/auth-validator");
const validate = require("../middlewares/validate-middleware");
const authMiddleware = require("../middlewares/auth-middleware");

router.route("/").get(authControllers.home);
router
  .route("/register")
  .post(validate(signupSchema), authControllers.register);
router.route("/login").post(authControllers.login);

router.route("/user").get(authMiddleware, authControllers.user);

module.exports = router;

Before proceeding, let's write our user logic within the controller file.

// *-------------------
// User Logic
// *-------------------

const user = async (req, res) => {
  try {
    // const userData = await User.find({});
    const userData = req.user;
    console.log(userData);
    return res.status(200).json({ msg: userData });
  } catch (error) {
    console.log(` error from user route ${error}`);
  }
};

In our authMiddleware file, the process of token verification is straightforward. Utilizing the model, we easily retrieve user details and pass them to the req properties.

const jwt = require("jsonwebtoken");
const User = require("../models/user-model");

const authMiddleware = async (req, res, next) => {
  const token = req.header("Authorization");

  if (!token) {
    // If you attempt to use an expired token, you'll receive a "401 Unauthorized HTTP" response.
    return res
      .status(401)
      .json({ message: "Unauthorized HTTP, Token not provided" });
  }

  // Assuming token is in the format "Bearer <jwtToken>, Removing the "Bearer" prefix"
  const jwtToken = token.replace("Bearer", "").trim();
  console.log(jwtToken);

  try {
    // Verifying the token
    const isVerified = jwt.verify(jwtToken, process.env.JWT_SECRET_KEY);
    console.log(isVerified);

    // getting the complete user details & also we don't want password to be sent
    const userData = await User.findOne({ email: isVerified.email }).select({
      password: 0,
    });

    req.token = token;
    req.user = userData;
    req.userID = user._id;

    // Move on to the next middleware or route handler
    next();
  } catch (error) {
    return res.status(401).json({ message: "Unauthorized. Invalid token." });
  }
};

module.exports = authMiddleware;

In Express.js, req (request) object is an object that contains information about the HTTP request. By adding custom properties to req, you can pass information between middleware functions or make it available in your route handlers.

In your authMiddleware:

  • req.token: This property is storing the JWT token extracted from the request header. You might use it later to perform additional actions or validations.

  • req.user: This property is storing the user data fetched from the database based on the information stored in the JWT token. It allows you to access user-related information in subsequent middleware functions or route handlers. This is often used to identify the authenticated user.

  • req.userID: This property is storing the _id of the authenticated user. It provides a convenient way to access the user's ID in your route handlers.