如何将反射器传递给Nest.js全局守卫?

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

我是 Nest.js 的新手,我有一个问题。 我有一个这样的角色守卫

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {
  }

  canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return user.role.some(role => !!roles.find(item => item === role));
  }

}

现在我想像这样使用这个守卫作为全局守卫

app.useGlobalGuards(new RolesGuard())

但是它说我需要将参数(反射器)传递给守卫,正如我在构造函数中提到的那样,现在可以像这样初始化反射器吗?

const reflector:Reflector = new Reflector();
app.useGlobalGuards(new RolesGuard(reflector))

或者有更好的方法吗?

dependency-injection nestjs guard
5个回答
3
投票

在官方 Nest JS 基础课程的“54 Protect Routes with Guards”讲座中,讲师指出,自己创建反射器实例并不是最佳实践。

解决依赖关系的更好方法是创建一个公共模块,并在那里注册你的守卫。这样,反射器实例将由嵌套运行时解析,您还可以为任何其他依赖项指定导入数组。

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { AuthTokenGuard } from './guards/auth-token.guard';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule],
  providers: [
    {
      provide: APP_GUARD,
      useClass: AuthTokenGuard,
    },
  ],
})
export class CommonModule {}

2
投票
  app.useGlobalGuards(new RolesGuard(new Reflector()));

它也正在工作。找不到更好的解决方案。


1
投票

虽然我的回答可能不会增加太多价值,但我只是想重申这是获取反射器的预期方法,这是 NestJS 创建者的引用

卡米尔米斯利维茨

当您手动创建实例时,您可以通过以下方式创建Reflector: 你自己:


new RoleGuard(new Reflector());

来源:https://github.com/nestjs/nest/issues/396#issuecomment-363111707


0
投票

2023年,NestJs 9,相关问题:

如果将请求范围的依赖项注入到全局注册的防护中,反射器将是未定义的。

您可以通过使用

ContextIdFactory
moduleRef.resolve()
解决此类依赖关系来解决此问题,而不是正常注入它们:

const req = context.switchToHttp().getRequest();
const contextId = ContextIdFactory.getByRequest(req);
this.moduleRef.registerRequestByContextId(req, contextId);
this.authorizationService = await this.moduleRef.resolve(
  RequestScopedService,
  contextId
);

参考资料:


0
投票

我安装了两个不同版本的

@nestjs/core
npm ls @nestjs/core
告诉我哪些依赖项导致了这个问题。

解决后,一切都按预期进行。

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