在Nest.JS中注入服务

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

我有KeysModule,可用于添加或删除API密钥。我需要这些密钥来保护某些路由免受未经授权的访问。为了保护这些路线,我创建了ApiGuard:

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';

@Injectable()
export class ApiGuard implements CanActivate {

async canActivate(
    context: ExecutionContext,
  ): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    return request.headers.api_key;
  }
}

然后我在路线中使用它:

 @Get('/protected')
 @UseGuards(ApiGuard)
 async protected(@Headers() headers: Api) {
   const key = await this.ks.findKey({ key: headers.api_key });
   if (!key || !key.active) return 'Invalid Key';
   return 'Your API key works';
 }

其中ks是用于检查密钥是否正确的KeyService。这个解决方案有效,但是很愚蠢。我必须复制并粘贴一些代码行,我想要使用这个防护(我的意思是路线中的线)。

我试图将所有逻辑移动到ApiGuard,但是我遇到了错误,KeyService无法注入ApiGuard类。为了解释,我在KeysModule的提供程序中有KeyService,但ApiGuard是全球使用的。

你知道怎么做吗?

node.js express nestjs
3个回答
0
投票

您可以在任何使用Injectable注释的对象中的防护中注入服务。如果您的ApiGuard需要KeyService,您有两种选择:

  • 在导入KeysModule的模块中添加ApiGuard。然后导入创建的模块以全局使用ApiGuard
  • 在KeysModule中添加ApiGuard并将其导出。

0
投票

也许为时已晚,但我遇到了同样的问题并找到了解决方案。也许有一个更好的,但它适合我:

将KeysModule定义为全局模块,您可以在nestjs docs中查看如何执行此操作:https://docs.nestjs.com/modules

你可以这样做之后:

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';

@Injectable()
export class ApiGuard implements CanActivate {

constructor(
@Inject('KeyService')
private readonly ks
) {}

const key = await this.ks.findKey();

"YOUR_CODE_HERE..."

}

希望对您或将来会坚持这一点的人有所帮助。


0
投票

在guard中注入服务。您可以创建一个全局模块。

// ApiModule
import {Module,Global} from '@nestjs/common';
import {KeyService} from '../';

@Global()
@Module({
    providers: [ KeyService ],
    exports: [KeyService]
})
export class ApiModule {}

然后像这样注入服务

// guard
export class ApiGuard implements CanActivate {
constructor(@Inject('KeyService') private readonly KeyService) {}
}
 async canActivate(context: ExecutionContext) {
    // your code
    throw new ForbiddenException();
  }

现在问题可以解决。但我有另一个问题。我想注入一些服务,但得到了这个错误:

Nest无法解析AuthGuard的依赖关系(?,+)。请确保索引[0]处的参数在当前上下文中可用。

这是我的解决方案:

要在KeyService中注入其他依赖项,比如nestjs docs说。

从任何模块外部注册的全局保护(使用上面示例中的useGlobalGuards())不能注入依赖项,因为这是在任何模块的上下文之外完成的。

这是他们的样本:

// app.module.js
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class ApplicationModule {}

它工作。现在我可以使用guard global而没有依赖错误。

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