NestJS请求管道user未定义:角色守卫取不到user对象
问题分析与解决方案
问题根源
你遇到的RolesGuard中user为undefined的问题,主要有两个核心原因:
- 守卫注册缺失或顺序错误:当前路由仅注册了
JwtAuthGuard,RolesGuard未被添加到@UseGuards中;若RolesGuard是全局注册,它会在异步的JwtAuthGuard完成认证前执行,此时req.user还未挂载。 - 同步守卫与异步认证不兼容:
JwtAuthGuard的validate方法是异步的,但RolesGuard的canActivate是同步方法,会在认证完成前执行,导致拿不到user。
解决方案
方案1:正确注册守卫并保证顺序
将RolesGuard与JwtAuthGuard一起加入路由的@UseGuards,且JwtAuthGuard在前(先完成认证,再执行授权逻辑):
@Get('get-framework-lists') @Roles(Role.SO) @UseGuards(JwtAuthGuard, RolesGuard) // 先认证,后授权 getFrameworkListsByCompany() { return this.dashboardService.getFrameworkListsByCompany(); }
方案2:将RolesGuard改为异步方法
由于JWT认证是异步操作,RolesGuard的canActivate需改为异步,确保等待认证完成后再获取user:
@Injectable() export class RolesGuard implements CanActivate { constructor(private reflector: Reflector) {} // 改为异步方法,返回Promise<boolean> async canActivate(context: ExecutionContext): Promise<boolean> { const requiredRole = this.reflector.getAllAndOverride<Role>(ROLES_KEY, [ context.getHandler(), context.getClass(), ]); if (!requiredRole) { return true; } console.log({ requiredRole }); const { user } = context.switchToHttp().getRequest(); // 增加兜底判断,避免user未定义时报错 if (!user) { return false; } return requiredRole === user.role; } }
额外检查项
- 确认
@Roles装饰器的元数据键ROLES_KEY定义正确:export const ROLES_KEY = 'roles'; export const Roles = (role: Role) => SetMetadata(ROLES_KEY, role); - 若使用全局守卫,需确保
RolesGuard在JwtAuthGuard之后注册,避免执行顺序错误。
内容的提问来源于stack exchange,提问作者vaibhav deep
相关产品推荐
相关产品推荐

