在上一篇文章中,我们介绍了 NestJS 的认证与授权实现。本文将深入探讨 NestJS 的请求处理流程,包括中间件、拦截器、管道和异常过滤器的使用。
请求生命周期
在 NestJS 中,请求处理流程按以下顺序执行:
- 中间件(Middleware)
- 守卫(Guards)
- 拦截器(Interceptors)- 前置处理
- 管道(Pipes)
- 控制器(Controller)
- 服务(Service)
- 拦截器(Interceptors)- 后置处理
- 异常过滤器(Exception Filters)
中间件实现
1. 函数式中间件
// src/common/middleware/logger.middleware.ts
import { Request, Response, NextFunction } from 'express';
export function loggerMiddleware(req: Request, res: Response, next: NextFunction) {
const { method, originalUrl, ip } = req;
const userAgent = req.get('user-agent') || '';
console.log(`[${method}] ${originalUrl} - ${ip} - ${userAgent}`);
// 记录请求开始时间
const start = Date.now();
// 响应结束后记录耗时
res.on('finish', () => {
const duration = Date.now() - start;
console.log(`[${method}] ${originalUrl} - ${res.statusCode} - ${duration}ms`);
});
next();
}
2. 类中间件
// src/common/middleware/auth.middleware.ts
import { Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthMiddleware implements NestMiddleware {
constructor(private jwtService: JwtService) {}
async use(req: Request, res: Response, next: NextFunction) {
const authHeader = req.headers.authorization;
if (!authHeader) {
next();
return;
}
try {
const token = authHeader.split(' ')[1];
const payload = await this.jwtService.verifyAsync(token);
req['user'] = payload;
next();
} catch (error) {
throw new UnauthorizedException('Invalid token');
}
}
}
3. 全局中间件
// src/app.module.ts
import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
import { AuthMiddleware } from './common/middleware/auth.middleware';
import { loggerMiddleware } from './common/middleware/logger.middleware';
@Module({
// ... 其他配置
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(loggerMiddleware, AuthMiddleware)
.exclude(
{ path: 'auth/login', method: RequestMethod.POST },
{ path: 'auth/register', method: RequestMethod.POST },
)
.forRoutes('*');
}
}

最低0.47元/天 解锁文章
1326

被折叠的 条评论
为什么被折叠?



