通过库共享时未注册 NestJS 自定义 PassportStrategy
Posted
技术标签:
【中文标题】通过库共享时未注册 NestJS 自定义 PassportStrategy【英文标题】:NestJS custom PassportStrategy not registered when shared through library 【发布时间】:2021-04-23 05:22:16 【问题描述】:我的任务是将我们的 NestJS 身份验证模块隔离到一个单独的共享库中,以便在多个 NestJS 项目之间重用它。每个项目都存在于每个自己的存储库中,并且共享库作为 npm 包导入。我正在使用 NestJS 的护照模块进行身份验证(使用 jwt 令牌),并且基本上只是遵循了有关如何实现它的官方文档。
我遵循了其他 NestJS 社区包的模式,到目前为止,我已经移动了大部分身份验证代码并确保它可以编译和运行。
现在,我遇到了一个问题。该应用程序不再识别自定义 jwt 护照策略,在我将它移到图书馆之后,我不知道为什么。我只是得到了例外:
未知的身份验证策略“jwt”
示例:
这是自定义护照策略和 AuthModule(实际版本更复杂,但这是一个可复制的最小示例)。 “父”项目和新库项目中的代码完全相同。
import Injectable, Module from '@nestjs/common';
import PassportStrategy from '@nestjs/passport';
import Strategy from 'passport-custom';
@Injectable()
export class CustomStrategy extends PassportStrategy(Strategy, 'custom')
async validate(request: Request): Promise<any>
console.log('Custom validation', request);
return true;
@Module()
export class AuthModule
static forRoot()
return
module: AuthModule,
providers: [CustomStrategy],
exports: [CustomStrategy],
;
这是我在 NestJS 应用程序中注册它的方式:
import Module from '@nestjs/common';
import PassportModule from '@nestjs/passport';
import AuthModule from '@my-org/common'; // Library version
// import AuthModule from './auth/AuthModule'; // Local version
@Module(
imports: [
AuthModule.forRoot(),
PassportModule.register( defaultStrategy: 'custom' )
]
)
export class CommonModule
export class CustomAuthGuard extends AuthGuard('custom')
当从同一个 NestJS 项目中引用 AuthModule 时,一切都会运行,我会收到 Custom validation
控制台消息。
当从我的 npm 库中导入 AuthModule 时,每当我提出请求时,我都会从护照中收到 Unknown authentication strategy "custom"
异常。
两边的代码完全一样。模块的用法是完全一样的,不管模块来自哪里。共享库使用与官方 NestJS 包相同的模式设置,例如 @nestjs/common 和 @nestjs/cqrs。库导出的任何其他注册服务都按预期工作(如果需要,我可以包含另一个最小示例来显示这一点)。
我错过了什么?如何使用单独的 npm 包共享我的自定义 NestJS PassportStrategy?
我已经花了一半的工作日试图解决这个问题,到目前为止,我认为这可能与策略注册的护照实例有关,但我不知道如何测试这个 - 或者,如果是这样的话,怎么解决呢。
【问题讨论】:
你必须在 @Module 装饰器的 "providers" 数组中导入你的策略,在 "imports" 数组中使用 PassportModule.register( defaultStrategy: 'jwt' ) 注册你的 'jwt' 策略 【参考方案1】:策略:
import Strategy from 'passport-custom';
import PassportStrategy from '@nestjs/passport';
import Injectable, UnauthorizedException from '@nestjs/common';
@Injectable()
export class CustomStrategy extends PassportStrategy(Strategy, "custom")
static key = "custom"
async validate(req: Request): Promise<User>
const valid = true;
if(!valid) throw new UnauthorizedException();
return id: "123", name: "test";
认证模块:
@Module(
imports: [PassportModule],
providers: [CustomStrategy]
)
export class AuthModule
控制器装饰器:
@UseGuards(AuthGuard(CustomStrategy.key))
【讨论】:
【参考方案2】:这样的东西对我有用:
import Injectable, Module from '@nestjs/common';
import PassportStrategy from '@nestjs/passport';
import Strategy from 'passport-custom';
@Injectable()
export class CustomStrategy extends PassportStrategy(Strategy, 'custom')
async validate(request: Request): Promise<any>
console.log('Custom validation', request);
return true;
@Module()
export class AuthModule
static forRoot()
return
module: AuthModule,
imports: [
PassportModule.register( defaultStrategy: 'custom' ),
],
providers: [CustomStrategy],
exports: [CustomStrategy, PassportModule],
;
【讨论】:
以上是关于通过库共享时未注册 NestJS 自定义 PassportStrategy的主要内容,如果未能解决你的问题,请参考以下文章