NestJS JWT 策略需要一个秘密或密钥

Posted

技术标签:

【中文标题】NestJS JWT 策略需要一个秘密或密钥【英文标题】:NestJS JWT Strategy requires a secret or key 【发布时间】:2020-07-08 03:06:01 【问题描述】:

在我的 NestJS Node 应用程序中,我已经使用 Passport 设置了 JWT 身份验证(根据 https://docs.nestjs.com/techniques/authentication),但是我试图将 JWT 密钥保留在使用内置 ConfigService 检索的环境文件中。

export class JwtStrategy extends PassportStrategy(Strategy) 
  constructor(private readonly configService: ConfigService) 
    super(
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: configService.get<string>('JWT_KEY'),
      signOptions:  expiresIn: '60s' 
    );
  

模块注册如下:

JwtModule.registerAsync(
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => 
        return 
          secret: configService.get<string>('JWT_KEY')
        ;
      ,
      inject: [ConfigService]
    )

启动应用时出现以下错误:

api: [Nest] 16244   - 03/27/2020, 10:52:00   [ExceptionHandler] JwtStrategy requires a secret or key +1ms

JWTStrategy 类似乎在 ConfigService 准备好提供 JWT Key 之前进行实例化,并在调用 configService.get&lt;string&gt;('JWT_KEY') 时在 Strategy 中返回 undefined。

我在这里做错了什么?在尝试检索任何环境变量之前,如何确保 ConfigService 已准备就绪?

更新: 整个 AuthModule 如下:

import  AuthController  from './auth.controller';
import  AuthService  from './auth.service';
import  JwtStrategy  from './strategies/jwt.strategy';
import  LocalStrategy  from './strategies/local.strategy';
import  SharedModule  from '../shared/shared.module';
import  UsersModule  from '../users/users.module';
import  ConfigModule, ConfigService  from '@nestjs/config';
import  JwtModule  from '@nestjs/jwt';
import  Module  from '@nestjs/common';
import  PassportModule  from '@nestjs/passport';

const passportModule = PassportModule.register( defaultStrategy: 'jwt' );
@Module(
  imports: [
    UsersModule,
    passportModule,
    JwtModule.registerAsync(
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => 
        return 
          secret: configService.get<string>('JWT_KEY')
        ;
      ,
      inject: [ConfigService]
    )
  ],
  providers: [ConfigService, AuthService, LocalStrategy, JwtStrategy],
  controllers: [AuthController],
  exports: [passportModule]
)
export class AuthModule 

【问题讨论】:

你可以添加你的PassportModule的注册吗? 我的 PassportModule 已注册:const passportModule = PassportModule.register( defaultStrategy: 'jwt' );,然后添加到我的导入数组中。 那你能把你的整个AuthModule展示出来吗?我看不到任何本质上的错误,并且我有一个设置,我将我的 ConfigService 传递给 Strategy 类工作 当然,为了清楚起见,将整个 AuthModule 添加到原始问题中。 即使我从 .env 获取密钥,我也遇到了同样的错误,我也尝试对密钥进行硬编码,但发生了同样的错误。 【参考方案1】:

我敢打赌,问题在于您不是 importConfigModule 添加到 AuthModule 中,而是将 ConfigService 直接添加到 providers 数组中。这意味着如果ConfigModuleConfigService 上进行任何类型的设置,它就不会再发生了。相反,您应该拥有的是这样的:

@Module(
  imports: [
    PassportModule.register(defaultStrategy: 'jwt' ),
    UserModule,
    JwtModule.registerAsync(
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => 
        return 
          secret: configService.get<string>('JWT_KEY')
        ;
      ,
      inject: [ConfigService]
    ),
    ConfigModule,
  ],
  providers: [LocalStrategy, JwtStrategy, AuthService],
  controllers: [AuthController],
  exports: [PassportStrategy],
)
export class AuthModule 

现在只要ConfigModule exports ConfigServiceAuthModule 应该可以正常启动。

【讨论】:

看来问题不在于将密钥拉入 AuthModule,而在于将其拉入 JWTStrategy 本身。我已遵循上述内容,非常感谢您的帮助。但是当 JWTStrategy 被实例化时,这似乎发生在 AuthModule?! 之前,configService 正在返回未定义的这个值。 您是否在其他任何地方添加了JwtStrategy?就像我说的那样,我有一个设置,其中一个策略注入了 ConfigService 并且它按预期工作 我刚刚意识到 JWTStrategy 中有一个错字。我放了 JWT_KET 而不是 JWT_KEY ...感谢大家的帮助。哦。 掌心 如何在 JwtStrategy 的超级调用中从 ASYNC 配置服务中获取 TOKEN 值? super(token: await authConfig.getConfig.jwtToken)我正在使用 AWS Secret Manager 来存储敏感值。 如果它在super() 电话中,则不能。您需要使用 async factory 进行异步调用,然后注入结果。

以上是关于NestJS JWT 策略需要一个秘密或密钥的主要内容,如果未能解决你的问题,请参考以下文章

NestJS JWT 策略认证。有效载荷对所有用户使用相同的安全密钥进行签名

使用带有动态/用户相关秘密的“nestjs/jwt”签名

我需要帮助来验证 jwt 是不是有效或以其他方式创建一个新的,如果发送的令牌不正确,则在 nestjs 中间件中返回错误

NestJs Passport jwt 未知策略

Passport 策略如何知道在 nestJS 中选择正确的 jwt 策略?

NestJS:使用 graphql 的 Passport LinkedIn 策略