Good Code
The good version authenticates in middleware and stores only the user context downstream routes need.
Lesson 08
Authenticate once in middleware and pass a safe user context to route handlers.
import type { NextFunction, Request, Response } from "express";
export async function requireUser(
req: Request,
res: Response,
next: NextFunction,
) {
// Middleware turns credentials into a small trusted user context.
const session = await sessions.findFromHeader(req.get("authorization"));
if (!session) {
res.status(401).json({ error: { message: "Authentication required." } });
return;
}
res.locals.user = {
id: session.userId,
role: session.role,
};
next();
}router.post("/:id/approve", async (req, res) => {
// Auth, authorization, and approval logic are mixed together.
const token = req.get("authorization");
const session = await sessions.findFromHeader(token);
if (!session || session.role !== "maintainer") {
res.status(403).json({ error: "Forbidden" });
return;
}
const review = await service.approveReview(req.params.id, session.userId);
res.json({ data: review });
});The good version authenticates in middleware and stores only the user context downstream routes need.
The bad version reparses credentials inside the route, mixing authentication, authorization, and review approval in one handler.