如何在NestJS控制器中让指定路由忽略@UseGuards()守卫?
让特定路由绕过控制器级JWT守卫的解决方案
嘿,这个需求我之前也遇到过,在NestJS里要实现控制器级加了JWT守卫,但某个方法要开放成公共路由,其实有挺优雅的实现方式,我给你一步步拆解:
1. 先整个@Public装饰器标记公共路由
首先我们需要一个自定义装饰器,用来告诉守卫“这个路由不用验证”。新建一个装饰器文件:
// src/common/decorators/public.decorator.ts import { SetMetadata } from '@nestjs/common'; export const Public = () => SetMetadata('isPublic', true);
这个装饰器的作用就是给路由打上一个isPublic的元数据标记,后面守卫会读取这个标记来判断是否跳过验证。
2. 修改你的JWT守卫逻辑
如果你之前用的是默认的AuthGuard('jwt'),现在我们需要自定义一个继承它的守卫,加上读取元数据的逻辑。新建一个守卫文件:
// src/common/guards/jwt-auth.guard.ts import { ExecutionContext, Injectable } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; import { Reflector } from '@nestjs/core'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { constructor(private reflector: Reflector) { super(); } canActivate(context: ExecutionContext) { // 先检查当前路由有没有被标记为公共路由 const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [ context.getHandler(), // 先看方法上的元数据 context.getClass(), // 再看控制器上的元数据 ]); // 如果是公共路由,直接放行 if (isPublic) { return true; } // 不是的话,走原来的JWT验证逻辑 return super.canActivate(context); } }
这里用到了NestJS的Reflector来读取我们之前设置的元数据,优先级是方法上的标记大于控制器上的,刚好符合我们的需求。
3. 在控制器里给目标方法加装饰器
现在回到你的BooksController,把原来的@UseGuards(AuthGuard('jwt'))换成我们自定义的JwtAuthGuard,然后给all()方法加上@Public()装饰器:
import { Public } from './common/decorators/public.decorator'; import { JwtAuthGuard } from './common/guards/jwt-auth.guard'; // 其他必要的导入... @ApiBearerAuth() @UseGuards(JwtAuthGuard) @ApiTags('books') @Controller('books') export class BooksController { @Post() async create(@Body() createBookVm: CreateBookVm) { //........ } @Public() // 给这个方法打上公共路由标记 @Get() async all() { //........ } }
偷懒的替代方案(不自定义装饰器)
如果你不想单独写装饰器文件,也可以直接在方法上用SetMetadata来标记:
import { SetMetadata } from '@nestjs/common'; // ... @SetMetadata('isPublic', true) @Get() async all() { //........ }
这种方式和用@Public装饰器效果完全一样,只是少了个封装的步骤,看你个人习惯选哪种就行。
这样改完之后,GET /books就会变成无需授权的公共路由,不携带accessToken访问也不会返回401,而POST /books依然会走JWT验证逻辑,完美符合你的需求~
内容的提问来源于stack exchange,提问作者Ramin Bateni Parvar
相关产品推荐
相关产品推荐

