javascript - Nest 无法解析装饰器内包装的防护的依赖关系

标签 javascript node.js typescript dependency-injection nestjs

我试图将一个提供者注入(inject)到一个装饰器中的防护中,但是 Nest 无法解析依赖项,从而出现下一个错误:

[ExceptionHandler] Nest can't resolve dependencies of the SecuredGuard (Reflector, ?). Please make sure that the argument at index [1] is available in the SecuredGuard context.

我的方法的主要目的是避免使用两个单独的装饰器,如下所示:


@Controller()
export class AppController {

  @Get()
  @Secured('admin')
  @UseGuards(SecuredGuard)
  getHello(): string {
    return this.appService.getHello();
  }

}

而是将 @UseGuards(SecuredGuard) 插入到我的自定义装饰器 @Secured('admin') 中,最终结果如下:

@Controller()
export class AppController {

  @Get()
  @Secured('admin')
  getHello(): string {
    return this.appService.getHello();
  }

}

这就是我实现自定义装饰器的方式:

export function Secured(...roles: string[]){ 

    const setMetadata = ReflectMetadata('roles', roles)
    const setupGuard = UseGuards(SecuredGuard)

    return (target: any, key?: string, descriptor?: any) => {
        setMetadata(target, key, descriptor);
        setupGuard(target, key, descriptor);
    }

}

这是我的 SecuredGuardAuthService 是无法解析的依赖项:

@Injectable()
export class SecuredGuard implements CanActivate {

  constructor(
    private readonly _reflector: Reflector,
    private readonly _authService: AuthService
  ) { }

  async canActivate(context: ExecutionContext): Promise<boolean> {...}
}

secured.guard.tssecured.decorator.ts 都是 secured.module.ts 的一部分

@Module({
    imports: [
        SecuredGuard,
        AuthModule
    ],
    exports: [
        SecuredGuard
    ],
    providers: [
        AuthService
    ]
})
export class SecuredModule {}

它使用从 auth.module.ts 导出的 AuthService

@Module({
  controllers: [
    AuthController
  ],
  providers: [
    AuthService
  ],
  imports: [
    EmailModule
  ],
  exports: [
    AuthService
  ]
})
export class AuthModule { }

并且 secured.module.ts 正在由 app.module.ts 导入

@Module({
  imports: [
    SecuredModule
  ],
  controllers: [
    AppController
  ],
  providers: [
    AppService
  ],
})
export class AppModule { }

我不知道我是否使用了适当的方法,或者即使这可能是我正在尝试做的事情,任何线索都将非常感激!

最佳答案

总的来说,您的解决方案似乎有效,请参阅此运行示例:

Edit custom-decorator-injection

<小时/>

但是,您的模块声明中存在一些错误:

1) 在您的 AppModule 中,AuthService 不可用,因为 AuthModule 既不是直接导入的,也不是由 导出的。安全模块。这就是您收到错误的原因。

2) 你不必在任何模块中声明你的守卫,它们只是全局可用的。仅将模块放入您的 imports 数组中。

3) 您多次提供AuthService,因此您将拥有它的不同实例。您应该只提供一次,然后仅导出(或重新导出)您的提供者,但不要再次提供。

4) ReflectMetadata 在 v6 中已弃用;请改用 SetMetadata

关于javascript - Nest 无法解析装饰器内包装的防护的依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55325182/

相关文章:

javascript - Node.js 错误 : EADDRINUSE on Elastic Beanstalk host

node.js - 如何在 ExpressJS 和 multer 中将数据从一个路由器传递到另一个路由器?

来自不同文件的 html View 中的 Angular 5 和枚举

javascript - 页面加载时滚动条显示在页眉和页脚上方

javascript - Appium android driver + js - 简单示例

javascript - 使用 Redux 时,将事件从演示组件传递到容器组件是否是反模式?

javascript - 错误的编译顺序

javascript - 将 CSS 类添加到 Ember.Select

typescript - 类型 'validate' 中的属性 'MappingService' 不可分配给基本类型 'IMappingService' typescript 2.8.0 中的同一属性

typescript - React Native 导航 (4.x) Prop 在屏幕之间变为空