Topic 52 of 55
JWT Authentication Middleware
Overview
Once the client has a JWT, they must send it back to the server in the `Authorization` header to access protected routes. We create an Express middleware to intercept the request, verify the token's signature, and extract the user data.
Syntax
javascript
const jwt = require('jsonwebtoken');
const requireAuth = (req, res, next) => {
// 1. Check if the Authorization header exists
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Unauthorized: No token provided' });
}
// 2. Extract the token (Remove "Bearer ")
const token = authHeader.split(' ')[1];
try {
// 3. Verify the token using the secret key
// If it's expired or tampered with, this will throw an error
const decodedPayload = jwt.verify(token, process.env.JWT_SECRET);
// 4. Attach the decoded payload to the request object
req.user = decodedPayload;
// 5. Move to the next middleware/route handler
next();
} catch (err) {
return res.status(403).json({ error: 'Forbidden: Invalid or expired token' });
}
};
module.exports = requireAuth;Common Pitfalls
- Always use `Bearer <token>` format in the Authorization header. It is the industry standard for OAuth and JWT.
- JWTs are stateless, meaning you cannot easily 'revoke' a token before it expires without maintaining a database blacklist (which defeats the purpose of statelessness). Keep token expiration times short.
Real-World Example
Applying the authentication middleware to protect specific routes:
example
javascript
const express = require('express');
const requireAuth = require('./middleware/auth');
const app = express();
// Public route (No token needed)
app.get('/public', (req, res) => res.send("Anyone can see this"));
// Protected route (Token required)
app.get('/dashboard', requireAuth, (req, res) => {
// Because requireAuth ran successfully, we know req.user exists!
res.send(`Welcome to your dashboard, user ID: ${req.user.userId}`);
});
// Protect an entire group of routes:
app.use('/api/secure', requireAuth);
app.get('/api/secure/data', (req, res) => res.send("Secure data"));