M
Middleware
Create reusable middleware functions with proper TypeScript types.
Code
typescript
1import { Request, Response, NextFunction } from "express";2 3// Extend Request type for custom properties4interface AuthenticatedRequest extends Request {5 user?: {6 id: number;7 email: string;8 roles: string[];9 };10}11 12// Logging middleware13function logger(14 req: Request,15 res: Response,16 next: NextFunction17): void {18 const start = Date.now();19 20 res.on("finish", () => {21 const duration = Date.now() - start;22 console.log(`${req.method} ${req.path} ${res.statusCode} - ${duration}ms`);23 });24 25 next();26}27 28// Authentication middleware29function authenticate(30 req: AuthenticatedRequest,31 res: Response,32 next: NextFunction33): void {34 const token = req.headers.authorization?.replace("Bearer ", "");35 36 if (!token) {37 res.status(401).json({ error: "No token provided" });38 return;39 }40 41 // Simulated token validation42 if (token === "valid-token") {43 req.user = {44 id: 1,45 email: "user@example.com",46 roles: ["user", "admin"],47 };48 next();49 } else {50 res.status(401).json({ error: "Invalid token" });51 }52}53 54// Role-based authorization middleware factory55function requireRole(...roles: string[]) {56 return (57 req: AuthenticatedRequest,58 res: Response,59 next: NextFunction60 ): void => {61 if (!req.user) {62 res.status(401).json({ error: "Not authenticated" });63 return;64 }65 66 const hasRole = roles.some((role) => req.user!.roles.includes(role));67 68 if (!hasRole) {69 res.status(403).json({ error: "Insufficient permissions" });70 return;71 }72 73 next();74 };75}76 77// Rate limiting middleware78function rateLimit(maxRequests: number, windowMs: number) {79 const requests = new Map<string, { count: number; resetTime: number }>();80 81 return (req: Request, res: Response, next: NextFunction): void => {82 const ip = req.ip || "unknown";83 const now = Date.now();84 const record = requests.get(ip);85 86 if (!record || now > record.resetTime) {87 requests.set(ip, { count: 1, resetTime: now + windowMs });88 next();89 return;90 }91 92 if (record.count >= maxRequests) {93 res.status(429).json({ error: "Too many requests" });94 return;95 }96 97 record.count++;98 next();99 };100}101 102// Usage example103// app.use(logger);104// app.use("/api", authenticate);105// app.use("/admin", requireRole("admin"));106// app.use(rateLimit(100, 60000)); // 100 requests per minute107 108export { logger, authenticate, requireRole, rateLimit, AuthenticatedRequest };Run this example locally
$ npx ts-node backend/middleware.ts