Creating a Middleware to Decode User from JWT 🔐
In the previous tutorial, we successfully created a Login Endpoint that sends a
JWT (JSON Web Token) to the user after login. But right now, anyone can access our
notes API routes without logging in — that is a big security problem!
To fix this, we need a middleware that checks every incoming request,
verifies the JWT token, and only allows access if the token is valid.
This is how real-world apps protect their private routes.
In this tutorial, we will learn:
What is a Middleware in Express JS?
Why we need a JWT verification middleware
Creating the fetchuser middleware
Decoding the user from the JWT token
Attaching the decoded user to the request object
Using the middleware to protect API routes
---
What is Middleware in Express JS?
A middleware is simply a function that runs between the incoming request and the final
route handler. It has access to the req (request), res (response),
and next function. When a middleware calls next(), Express moves on to the
next function in the chain — either the next middleware or the route handler.
// Basic middleware structure
function myMiddleware(req, res, next) {
// do something
next(); // pass control to the next handler
}
---
Why Do We Need a JWT Middleware?
After a user logs in, our server sends them a JWT token. On every future request
(like fetching, adding, or deleting notes), the user sends that token back inside the
request header. Our middleware will:
Read the JWT token from the request header.
Verify the token using our secret key.
Decode the user's id from the token.
Attach the user to req.user so route handlers can use it.
Block the request with a 401 Unauthorized error if the token is invalid or missing.
---
Step 1: Create the middleware File
Inside your project root, create a new folder called middleware and inside it
create a file called fetchuser.js.
cloudnotebook-backend/
middleware/
fetchuser.js
models/
routes/
index.js
---
Step 2: Install and Import jsonwebtoken
Make sure jsonwebtoken is already installed. If not, install it now:
npm install jsonwebtoken
---
Step 3: Write the fetchuser Middleware
Open middleware/fetchuser.js and write the following code.
This middleware reads the token from the header, verifies it, and attaches the decoded user to req.user.
const jwt = require("jsonwebtoken");
const JWT_SECRET = "your$ecretKey123"; // Use same secret as in auth routes
const fetchuser = (req, res, next) => {
// Get the token from the request header
const token = req.header("auth-token");
// If no token found, deny access
if (!token) {
return res.status(401).json({ error: "Access Denied. No token provided." });
}
try {
// Verify the token and decode the user data
const decoded = jwt.verify(token, JWT_SECRET);
// Attach the decoded user to the request object
req.user = decoded.user;
// Move to the next middleware or route handler
next();
} catch (error) {
return res.status(401).json({ error: "Invalid Token. Please authenticate." });
}
};
module.exports = fetchuser;
---
Step 4: How the Token Is Sent by the Frontend
When the user logs in, they receive a JWT token. For every protected request after that,
the frontend must send the token inside the HTTP header like this:
// Frontend sending token with every protected request
fetch("http://localhost:5000/api/notes/fetchallnotes", {
method: "GET",
headers: {
"auth-token": "your_jwt_token_here",
"Content-Type": "application/json",
},
});
---
Step 5: Use the Middleware in a Protected Route
Now let's use our fetchuser middleware to protect the notes route.
Import it in your routes/notes.js file and add it before the route handler.
const express = require("express");
const router = express.Router();
const fetchuser = require("../middleware/fetchuser");
// Protected Route — only accessible with a valid JWT token
// GET /api/notes/fetchallnotes
router.get("/fetchallnotes", fetchuser, async (req, res) => {
try {
// req.user is now available thanks to our middleware
console.log("Logged in user ID:", req.user.id);
res.json({ message: "Notes fetched successfully!", userId: req.user.id });
} catch (error) {
console.error(error.message);
res.status(500).send("Internal Server Error");
}
});
module.exports = router;
---
How the Middleware Flow Works
| Step |
What Happens |
| 1. Request arrives |
Frontend sends a GET/POST request with auth-token in the header |
| 2. Middleware runs |
fetchuser middleware intercepts the request before the route handler |
| 3. Token missing? |
Returns 401 Unauthorized — request is blocked |
| 4. Token invalid? |
Returns 401 Invalid Token — request is blocked |
| 5. Token valid |
User is decoded, attached to req.user, and next() is called |
| 6. Route handler runs |
The actual route logic runs with access to req.user.id |
---
⚠️ Important Note
Always store your JWT_SECRET key in a .env file — never hardcode it directly in your source code.
Add .env to .gitignore so it is never pushed to GitHub.
Example .env file:
JWT_SECRET=your$ecretKey123
Usage in code:
const JWT_SECRET = process.env.JWT_SECRET;
---
Features and Learnings:-
Understood what middleware is in Express JS and how it works.
Learned why JWT middleware is essential for protecting private routes.
Created the fetchuser middleware to verify and decode JWT tokens.
Attached the decoded user to req.user for use inside route handlers.
Learned how the frontend sends JWT token inside request headers.
Applied the middleware to a protected notes route.
Handled unauthorized access with proper 401 error responses.
Learned best practices for storing JWT secret in .env files.