如何在Nest框架中编写拦截器并实现认证功能?
在Nest框架中编写拦截器(含认证示例)
拦截器是Nest基于**面向切面编程(AOP)**设计的核心组件,本质是被@Injectable()装饰、实现NestInterceptor接口的类,可处理认证、日志、请求/响应转换、异常统一处理等场景。下面以认证功能为例,一步步实现自定义拦截器:
1. 创建认证拦截器类
新建拦截器文件(如auth.interceptor.ts),实现NestInterceptor接口,核心逻辑写在intercept方法中:
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, UnauthorizedException } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { Observable } from 'rxjs'; @Injectable() export class AuthInterceptor implements NestInterceptor { constructor(private readonly jwtService: JwtService) {} intercept(context: ExecutionContext, next: CallHandler): Observable<any> { // 获取HTTP请求对象 const request = context.switchToHttp().getRequest(); // 从请求头提取Bearer token const token = this.extractTokenFromHeader(request); if (!token) { throw new UnauthorizedException('未提供认证token'); } try { // 验证并解析token,获取用户信息 const payload = this.jwtService.verify(token); // 将用户信息挂载到请求对象,供后续路由使用 request.user = payload; } catch (err) { throw new UnauthorizedException('无效的认证token'); } // 继续执行后续路由逻辑 return next.handle(); } // 从请求头提取token的辅助方法 private extractTokenFromHeader(request: Request): string | undefined { const [type, token] = request.headers['authorization']?.split(' ') ?? []; return type === 'Bearer' ? token : undefined; } }
2. 注册拦截器
拦截器有三种注册方式,按需选择:
全局注册(作用于所有路由)
在main.ts中通过app.useGlobalInterceptors注册:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { AuthInterceptor } from './auth.interceptor'; import { JwtModule } from '@nestjs/jwt'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 全局注册时手动获取依赖实例 const jwtService = app.get(JwtService); app.useGlobalInterceptors(new AuthInterceptor(jwtService)); await app.listen(3000); } bootstrap();
模块级注册(作用于当前模块下所有路由)
在对应模块中通过APP_INTERCEPTOR令牌实现模块内全局生效:
import { Module } from '@nestjs/common'; import { APP_INTERCEPTOR } from '@nestjs/core'; import { AuthInterceptor } from './auth.interceptor'; import { JwtModule } from '@nestjs/jwt'; @Module({ imports: [JwtModule.register({ secret: 'your-secret-key' })], providers: [ { provide: APP_INTERCEPTOR, useClass: AuthInterceptor, }, ], }) export class AppModule {}
局部注册(作用于指定控制器/路由)
使用@UseInterceptors装饰器直接标注在控制器或路由上:
import { Controller, Get, UseInterceptors } from '@nestjs/common'; import { AuthInterceptor } from './auth.interceptor'; @Controller('protected') @UseInterceptors(AuthInterceptor) export class ProtectedController { @Get() getProtectedData() { return { message: '这是受保护的数据' }; } }
拦截器的其他常用场景
除了认证,拦截器还能实现:
- 响应转换:修改
next.handle()返回的Observable,统一接口响应格式 - 异常捕获:通过
catchError操作符捕获路由异常并统一处理 - 性能监控:记录请求开始/结束时间,统计接口耗时
- 日志记录:记录请求URL、方法、参数等信息
内容的提问来源于stack exchange,提问作者Joaquim Mendes
相关产品推荐
相关产品推荐

