Securing API Routes with Authentication Middleware
Securing API Routes with Authentication Middleware
Last updated: 3/7/2025
Securing API Routes with Authentication Middleware
π Introduction
Now that weβve implemented user authentication and JWT-based login, we need to protect API routes so only authenticated users can access them.
In this lesson, youβll learn:
β
How to create authentication middleware in Express.js.
β
How to secure API routes using JWT tokens.
β
How to return proper error responses for unauthorized access.
π 1. Why Do We Need Authentication Middleware?
Right now, anyone can access our API routes.
We need middleware to:
πΉ Verify the JWT token before allowing access.
πΉ Reject unauthorized requests with a 401 Unauthorized
error.
πΉ Pass valid users to the next middleware function.
π 2. Creating Authentication Middleware
Create a new file middleware/auth.js
and add the following code:
const jwt = require("jsonwebtoken"); module.exports = function (req, res, next) { const token = req.header("Authorization"); // Check if token is provided if (!token) { return res.status(401).json({ error: "Access denied. No token provided." }); } try { // Verify token const decoded = jwt.verify(token.replace("Bearer ", ""), process.env.JWT_SECRET); req.user = decoded; // Attach user data to request next(); // Continue to the protected route } catch (error) { res.status(400).json({ error: "Invalid token" }); } };
β Checks for token in the Authorization
header.
β Verifies the token using jwt.verify()
.
β Attaches user info (req.user
) to the request for later use.
β Returns 401 Unauthorized
if the token is missing or invalid.
π 3. Protecting API Routes with Middleware
Now, weβll protect a profile route so only authenticated users can access it.
Modify routes/auth.js
:
const authMiddleware = require("../middleware/auth"); router.get("/profile", authMiddleware, async (req, res) => { res.json({ message: "Welcome to your profile!", userId: req.user.userId }); });
β The authMiddleware
runs before handling the request.
β If valid, the user can access the /profile
route.
β If invalid, the API returns an error response.
π 4. Testing the Protected Route
β
1οΈβ£ Accessing /profile
Without a Token
β Request:
GET /auth/profile
β Response:
{ "error": "Access denied. No token provided." }
β
2οΈβ£ Accessing /profile
With a Valid Token
β Request:
GET /auth/profile Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
β Response:
{ "message": "Welcome to your profile!", "userId": "656a7f3bc4d91b0012a8d849" }
π 5. Protecting Other Routes
We can now secure any route by adding authMiddleware
.
Example: Protecting a GET /users route:
router.get("/users", authMiddleware, async (req, res) => { const users = await User.find(); res.json(users); });
π― Summary
- Authentication middleware ensures that only logged-in users can access protected routes.
- JWT tokens are verified before allowing access.
- Unauthorized requests return a 401 Unauthorized error.
- The middleware can be reused to protect multiple routes.
β Next Lesson: Project β TodoList with Authentication
Now that we have authentication and protected routes, weβll apply these concepts in a TodoList API with authentication. π