无法从我的 RoleGuard、nestJS 检索 request.user

问题描述 投票:0回答:4

我正在制作一个用于特定控制器的角色防护。我遵循在 app.module 级别全局使用它的文档方式。这是代码。

    async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  app.useGlobalGuards(new RoleGuard(new Reflector()));
  await app.listen(3000);
}

现在我的 RoleGuard 代码工作正常,并在预期时返回 console.logged 结果,只是护照中间件应添加的 request.user 不存在。这是守卫的代码:

    export class RoleGuard implements CanActivate {
  constructor(private reflector: Reflector) {}
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      console.log('no roles');
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    console.dir(user);
    return this.matchRoles(roles, user);
  }

console.dir 显示未定义,但是当尝试 console.dir 请求时它工作正常,只是它不包含用户属性。

passport.js nestjs
4个回答
1
投票

听起来你找到了自己的问题,

AuthGuard
需要在
RolesGuard
之前运行。这样做的原因是
passport
负责设置
req.user
属性,因此
AuthGuard
(在后台使用通行证)需要首先运行。所有 Nest 增强器都有一个定义的运行顺序,如请求生命周期页面中记录的那样。首先运行全局增强器(通过 app.useGlobal*()
APP_*
绑定的增强器)。然后是控制器级增强器,最后是方法级增强器。
为了允许全局设置 

RolesGuard

,您可以做的事情是创建一个

extends AuthGuard()
的防护,并读取一些有关
AuthGuard
是否应该触发的自定义元数据。如果元数据存在,则以短路形式返回
true
,如果不存在,则在自定义守卫的
super.canActivate()
方法中返回
canActivate
。您可以像设置角色元数据一样
设置此元数据,
文档中也有概述

将控制器下的 Guard Decorator 移离 main.ts 现在可以正确显示 request.user 对象。我假设护照中间件稍后会附加用户属性,因此在应用程序的全局级别上看不到它。我希望对这个问题有更多的见解,因为这只是我自己的假设

0
投票

您可以尝试以下代码片段,它与您的代码几乎相似,所以我给出整个片段:

0
投票
@Injectable() export class RolesGuard implements CanActivate { constructor(private reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { // get the role of the request const roles = this.reflector.get<Role[]>("roles", context.getHandler()); if (!roles) { return true; } // now get the current user const request = context.switchToHttp().getRequest(); const requestData = request; return roles.some((role) => requestData.user.role.toLowerCase() === role); } }

对于我的情况,Role[] 来自用户模型的 userRole。这是我的用例:
export enum Role {
  ADMIN = "admin",
  USER = "user",
}

您需要从代码库导入它。
    

确保 RoleGuard 不是 Global Guard。

0
投票
全局守卫 > 控制器守卫 > API 端点守卫

您可以在这里阅读更多相关信息:

https://docs.nestjs.com/guards#binding-guards

© www.soinside.com 2019 - 2024. All rights reserved.