Auth middleware
Right now, anyone can call every route in your API. This part adds a middleware that checks for a valid JSON Web Token before letting a request through to protected routes.
Installing a JWT library
npm install jsonwebtoken
Writing the middleware
The middleware reads the Authorization header, verifies the token, and attaches the decoded payload to req for downstream routes to use:
const jwt = require('jsonwebtoken');
function requireAuth(req, res, next) {
const header = req.headers.authorization;
if (!header?.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Missing bearer token' });
}
try {
req.user = jwt.verify(header.slice(7), process.env.JWT_SECRET);
next();
} catch {
res.status(401).json({ error: 'Invalid or expired token' });
}
}
Protecting a route
Add the middleware as a second argument to any route you want to protect:
app.get('/api/users/:id', requireAuth, asyncHandler(async (req, res) => {
// req.user is now available here
const { rows } = await pool.query(
'SELECT id, name, email FROM users WHERE id = $1',
[req.params.id]
);
res.json(rows[0]);
}));
This middleware only verifies a token — it doesn't issue one. A real login route that checks a password and signs a token with jwt.sign() is a natural next step once this series ends, and follows the same pattern.
Try it yourself
Generate a token manually with jwt.sign({ id: 1 }, process.env.JWT_SECRET) in a Node REPL, then call your protected route with and without an Authorization: Bearer <token> header to see both code paths. Last part: deploying this for free.