Typed Express Middleware With Request State
Extend Express request types through declaration merging so middleware can attach authenticated user data that later handlers read with full type safety.
Code
import express, { type NextFunction, type Request, type Response } from "express";
export interface AuthUser {
id: string;
roles: string[];
}
declare module "express-serve-static-core" {
interface Request {
user?: AuthUser;
}
}
export function requireAuth(req: Request, res: Response, next: NextFunction): void {
const token = req.header("authorization")?.replace(/^Bearer /, "");
if (!token) {
res.status(401).json({ error: "missing token" });
return;
}
try {
req.user = verifyToken(token);
next();
} catch (error) {
res.status(401).json({ error: (error as Error).message });
}
}
function verifyToken(token: string): AuthUser {
const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64").toString());
return { id: payload.sub, roles: payload.roles ?? [] };
}
const app = express();
app.use(requireAuth);
Report a problem with this exampleOpens a pre-filled issue on GitHub.