NestJS не может разрешить зависимости JWT_MODULE_OPTIONS

Я не смог скомпилировать с этой ошибкой:

Nest не может разрешить зависимости JWT_MODULE_OPTIONS (?). Пожалуйста, убедитесь, что аргумент по индексу [0] доступен в контексте JwtModule. + 52ms

Я видел похожие проблемы с зависимостями от модулей и сервисов, но они не работали для меня. Используя JwtModule в моем auth.module.ts:

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, поэтому я понижаю его, но проблема не устранена.

3 ответа

Решение

Сначала вы смешиваете конфигурацию TypeORMModule с конфигурацией JWTModule.

Согласно с @nestjs/jwt исходный коддокументы), secretOrPrivateKey а также signOptions, Все остальные параметры, похоже, являются частью конфигурации TypeORMModule.

Во-вторых, ConfigService (который является зависимостью [0] модуля JWT), кажется, не существует где-либо в вашем коде. Таким образом, вы пропускаете импорт в модуль, в котором существует ConfigService.

Вот почему загрузка зависимостей терпит неудачу (и именно это означает ошибка)

Обратите внимание, что в вашем коде отсутствует импорт модуля (ConfigModule в следующем примере), который является модулем, который содержит ConfigService. В противном случае нет способа внедрить этот ConfigService из ниоткуда!

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

Я как-то заставил его работать, добавив

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

в app.module.ts и auth.module.ts

Можно сделать для него отдельный модуль (SharedModule)

убедитесь, что у вас установлены следующие пакеты

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

(необязательно, если вы используете MongoDB/Mongoose)

        npm i --save @nestjs/mongoose 

общий.модуль.тс

      @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())
Другие вопросы по тегам