You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中RolesGuard先于JwtGuard触发致request.user为空求助

问题分析与解决方案

核心原因

你遇到的问题本质是全局注册的RolesGuard执行顺序早于控制器级的JwtAuthGuard,导致request.user还未被JWT守卫赋值就被角色守卫读取,最终返回undefined。具体细节:

  • NestJS守卫的执行优先级是:全局守卫 → 控制器级守卫 → 方法级守卫
  • 你在main.ts中全局注册了RolesGuard,它会在所有请求的最开始执行,此时控制器上的JwtAuthGuard还未触发,request.user自然为空
  • 当给方法添加@Roles('ADMIN')后,全局RolesGuard读取到requiredRoles,因user为空直接返回false,后续JwtAuthGuard完全没有执行机会
  • 移除@Roles装饰器时,全局RolesGuard因获取不到requiredRoles直接返回true,JwtAuthGuard得以正常执行并赋值user

解决方案

方案1:移除全局RolesGuard,按需组合使用

删除main.ts中的全局RolesGuard注册代码,在需要角色校验的方法上同时指定两个守卫(注意顺序,JWT守卫在前):

@UseGuards(JwtAuthGuard)
export class UserController {
...
  @Delete(':userId')
  @UseGuards(JwtAuthGuard, RolesGuard) // 确保JwtAuthGuard先执行,完成user赋值
  @Roles('ADMIN')
  async deleteUser(
    @Request() req: CustomRequest,
    @Param('userId') userId: string,
  ) {
    console.log('Controller - User:', req.user);
  }
}

注:控制器上的@UseGuards(JwtAuthGuard)可保留,作为该控制器所有接口的默认JWT校验;方法上重复写是为了和RolesGuard组成守卫链,保证执行顺序。

方案2:保留全局RolesGuard,调整JwtAuthGuard执行优先级

若需要全局生效RolesGuard,可通过两种方式确保JwtAuthGuard先执行:

  1. 将JwtAuthGuard也设为全局守卫,且先于RolesGuard注册:
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const reflector = app.get(Reflector);
  // 全局守卫按注册顺序执行,先注册JwtAuthGuard保证优先级
  app.useGlobalGuards(new JwtAuthGuard(), new RolesGuard(reflector));
  app.use(new LocalNetworkMiddleware().use);

  await app.listen(3001);
}
  1. 利用守卫优先级(NestJS v10+支持):
    给JwtAuthGuard设置更高优先级:
@Injectable({ priority: 1 }) // 数值越大优先级越高
export class JwtAuthGuard extends AuthGuard('jwt') {
  // 你的JwtAuthGuard逻辑
}

给RolesGuard设置更低优先级:

@Injectable({ priority: 0 })
export class RolesGuard implements CanActivate {
  // 你的RolesGuard逻辑
}

额外说明

  • 方法上的@UseGuards(RolesGuard)可以删除,全局已注册的情况下重复添加会导致守卫执行两次,无必要。
  • 调试时可给每个守卫的canActivate方法加日志,明确执行顺序,方便排查问题。

内容的提问来源于stack exchange,提问作者Zirek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:42:33