中间件、守卫、拦截器
中间件是对 HTTP 请求的前处理(类似 Express 的中间件)
守卫是访问控制的门卫
拦截器是处理方法执行前后逻辑的过滤器
| 特性 | 中间件(Middleware) | 守卫(Guard) | 拦截器(Interceptor) |
|---|---|---|---|
| 作用阶段 | 请求进入路由处理器 之前 | 路由处理器执行 之前 | 路由处理器调用 前后 |
| 主要用途 | 请求预处理,如日志、鉴权等 | 权限控制、角色判断等 | 响应转换、日志记录、异常捕获、缓存等 |
| 是否依赖装饰器 | ❌(使用函数或类注册) | ✅(用 @UseGuards() 装饰器) |
✅(用 @UseInterceptors() 装饰器) |
| 是否支持 DI | ✅(类中间件支持依赖注入) | ✅ | ✅ |
| 应用范围 | 全局或模块级别(不能单独用于路由) | 路由级别/控制器级别/全局 | 路由级别/控制器级别/全局 |
| 返回值影响响应? | ❌(一般不返回响应) | ✅(返回 false 拒绝请求) | ✅(可以修改请求和响应) |
| 类似 Express 哪个概念 | Express 的中间件 | 类似于权限校验中间件(但更强大) | 类似 AOP 或 axios 的拦截器概念 |
1. 中间件 Middleware
处理原始请求对象,适合做日志、请求体解析、跨域设置等
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log(`[LoggerMiddleware] ${req.method} ${req.originalUrl}`);
next();
}
}
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { Test1Service } from './test1.service';
import { Test1Controller } from './test1.controller';
import { LoggerMiddleware } from './middleware/index';
@Module({
controllers: [Test1Controller],
providers: [Test1Service],
})
export class Test1Module {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
}
forRoutes精确指定它应用在哪些路由上,上述案列中*全路径,每个方法都起效
1.forRoutes({ path: 'user', method: RequestMethod.GET }); // 只应用于 GET /user
2.forRoutes({ path: 'user', method: RequestMethod.GET },{ path: 'user/:id', method: RequestMethod.POST }); //多路径
2. 守卫 Guard
决定是否允许进入路由处理器,比如鉴权、角色判断。
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(context: ExecutionContext): boolean {
console.log('guardguardguard');
const request = context
.switchToHttp()
.getRequest<{ headers: { authorization?: string } }>();
return request.headers?.authorization === 'Bearer mytoken'; // 鉴权逻辑
// return true;
}
}
// 控制器
@UseGuards(AuthGuard)
@Get('/guard')
getGuard() {
return '1111';
}
3. 拦截器 Interceptor
可在方法执行前/后插入逻辑,比如统一返回格式、缓存处理、异常捕获等。
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
const now = Date.now();
return next
.handle()
.pipe(
tap(() => console.log(`After... ${Date.now() - now}ms`)),
);
}
}
// 控制器中使用 @UseInterceptors(LoggingInterceptor) @Get('data') getData() { return { id: 1 }; }
浙公网安备 33010602011771号