【问题标题】:NestJS can't resolve dependencies of the JWT_MODULE_OPTIONSNestJS 无法解析 JWT_MODULE_OPTIONS 的依赖关系
【发布时间】:2019-12-19 04:06:15
【问题描述】:

我编译失败,出现这个错误:

Nest 无法解析 JWT_MODULE_OPTIONS (?) 的依赖关系。请确保索引 [0] 处的参数在 JwtModule 上下文中可用。 +52 毫秒

我看到了与模块和服务类似的依赖问题,但它们对我不起作用。在我的 auth.module.ts 中使用 JwtModule:

import { JwtModule } from '@nestjs/jwt';
@Module({
    imports: [
        TypeOrmModule.forFeature([User, Role]),
        ConfigModule,
        PassportModule.register({ defaultStrategy: 'jwt' }),
        JwtModule.registerAsync({
            inject: [ConfigService],
            useFactory: async (configService: ConfigService) => ({
                secretOrPrivateKey: config.jwtSecret,
                type: configService.dbType as any,
                host: configService.dbHost,
                port: configService.dbPort,
                username: configService.dbUsername,
                password: configService.dbPassword,
                database: configService.dbName,
                entities: ['./src/data/entities/*.ts'],
                signOptions: {
                    expiresIn: config.expiresIn,
                },
            }),
        }),

    ],
    providers: [AuthService, JwtStrategy],
    controllers: [AuthController],
})
export class AuthModule { }

我不知道如何修复这个错误...使用 jwt 6.1.1

编辑:在我之前的项目中使用 jwt 6.0.0,所以我降级了它,但问题没有解决。

【问题讨论】:

  • 真正快速的问题:为什么要将数据库选项传递给 JWT 模块?

标签: typescript module nestjs


【解决方案1】:

首先,您将 TypeORMModule 配置与 JWTModule 配置混合使用。

根据@nestjs/jwtsource code(和docs)、secretOrPrivateKeysignOptions。所有其他参数似乎都是 TypeORMModule 配置的一部分。

其次,ConfigService(它是 JWT 模块的依赖项 [0])似乎不存在于您的代码中的任何位置。因此,您缺少对内部存在 ConfigService 的模块的导入。

这就是依赖加载失败的原因(这就是抛出错误的意思)

请注意,在您的代码中,您缺少一个模块的导入(以下示例中的ConfigModule),它是包含 ConfigService 的模块。否则没有办法从任何地方注入这个 ConfigService!

JwtModule.registerAsync({
  imports: [ConfigModule], // Missing this
  useFactory: async (configService: ConfigService) => ({
    signOptions: {
       expiresIn: config.expiresIn,
    },
    secretOrPrivateKey: config.jwtSecret,
  }),
  inject: [ConfigService], 
}),

【讨论】:

【解决方案2】:

我以某种方式通过添加使其工作

JwtModule.registerAsync({
  imports: [ConfigModule], // Missing this
  useFactory: async (configService: ConfigService) => ({
    signOptions: {
       expiresIn: config.expiresIn,
    },
    secretOrPrivateKey: config.jwtSecret,
  }),
  inject: [ConfigService], 
}),

app.module.tsauth.module.ts

【讨论】:

    【解决方案3】:

    你可以为它制作一个单独的模块(SharedModule)

    确保您已安装以下软件包

    npm i --save @nestjs/jwt
    npm i --save @nestjs/passport
    

    (可选,如果您使用 MongoDB/Mongoose)

      npm i --save @nestjs/mongoose 
    

    shared.module.ts

    @NgModule({
       imports: [
          PassportModule.register({
              defaultStrategy: 'jwt',
            }),
            JwtModule.register({
              secret: process.env.JWT_SECRET_KEY,
              signOptions: {
                expiresIn: '2 days',
              },
            }),
        
       ],
       providers: [JwtStrategy],
       exports: [JwtStrategy, PassportModule]
    })
    

    jwt.strategy.ts

    @Injectable()
    export class JwtStrategy extends PassportStrategy(Strategy) {
      constructor(@InjectModel('User') private collection: Model<User>) {
        super({
          jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
          secretOrKey: process.env.JWT_SECRET_KEY,
        });
      }
    
      async validate(payload: JwtPayload): Promise<User> {
        const { username } = payload;
        const user = await this.collection.findOne({ username });
    
        if (!user) {
          throw new UnauthorizedException('JwtStrategy unauthorized');
        }
    
        return user;
      }
    }
    

    现在您想在哪里使用它,只需在您的模块 SharedModule 中导入即可。 在您的控制器中使用以下装饰器

    @UseGuards(AuthGuard())
    

    【讨论】:

      猜你喜欢
      • 2019-12-19
      • 2018-11-22
      • 2018-12-25
      • 2021-11-24
      • 2020-05-27
      • 2020-01-14
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多