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

NestJS技术求助:自定义RolesGuard中无法获取JWT认证用户信息

解决NestJS自定义RolesGuard无法获取request.user的问题

这个问题的核心是守卫的执行顺序以及当前路由缺少JWT认证守卫的应用——用户信息还没被挂载到请求对象上,RolesGuard自然拿不到request.user。

问题分析

你提到getProfile接口能正常获取req.user,说明这个接口肯定应用了负责JWT解析的AuthGuard('jwt')(要么是局部配置,要么是全局注册)。但你的findAll接口只添加了RolesGuard,没有让请求先经过JWT认证步骤:没有认证流程,NestJS就不会把用户信息注入到request对象里,所以console.log(request.user)才会输出undefined。

解决方案

你需要确保AuthGuard('jwt')在RolesGuard之前执行,有两种可行方式:

1. 局部在路由上同时应用两个守卫(更灵活)

修改findAll接口的守卫配置,把AuthGuard('jwt')放在RolesGuard前面——NestJS会按照@UseGuards()的参数顺序依次执行守卫,只有前面的守卫通过后,才会执行后续守卫:

@Get()
@UseGuards(AuthGuard('jwt'), RolesGuard) // 先完成JWT认证,再执行角色鉴权
@Roles('admin')
findAll() {
  return this.usersService.findAll();
}

2. 全局注册JWT认证守卫

如果你的大部分接口都需要JWT认证,可以在AppModule里全局注册AuthGuard('jwt'),这样所有路由都会自动经过JWT认证,之后只需要在需要角色鉴权的接口上单独添加RolesGuard即可:

// src/app.module.ts
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';

@Module({
  imports: [/* 你的其他模块 */],
  providers: [
    {
      provide: APP_GUARD,
      useClass: AuthGuard('jwt'),
    },
  ],
})
export class AppModule {}

之后findAll接口可以保持原有写法,全局守卫已经完成了JWT认证并挂载了request.user:

@Get()
@UseGuards(RolesGuard)
@Roles('admin')
findAll() {
  return this.usersService.findAll();
}

验证逻辑

修改后,你可以在RolesGuard里再次打印request.user,就能看到正常的用户信息了。之后你就可以基于request.user的角色信息和reflector获取到的roles元数据,完成角色鉴权逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:58:09