我试图将一个提供者注入(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);
}
}
这是我的 SecuredGuard
,AuthService
是无法解析的依赖项:
@Injectable()
export class SecuredGuard implements CanActivate {
constructor(
private readonly _reflector: Reflector,
private readonly _authService: AuthService
) { }
async canActivate(context: ExecutionContext): Promise<boolean> {...}
}
secured.guard.ts
和 secured.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 { }
我不知道我是否使用了适当的方法,或者即使这可能是我正在尝试做的事情,任何线索都将非常感激!
最佳答案
总的来说,您的解决方案似乎有效,请参阅此运行示例:
<小时/>但是,您的模块声明中存在一些错误:
1) 在您的 AppModule
中,AuthService
不可用,因为 AuthModule
既不是直接导入的,也不是由 导出的。安全模块
。这就是您收到错误的原因。
2) 你不必在任何模块中声明你的守卫,它们只是全局可用的。仅将模块放入您的 imports
数组中。
3) 您多次提供AuthService
,因此您将拥有它的不同实例。您应该只提供一次,然后仅导出
(或重新导出)您的提供者,但不要再次提供。
4) ReflectMetadata
在 v6 中已弃用;请改用 SetMetadata
。
关于javascript - Nest 无法解析装饰器内包装的防护的依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55325182/