NestJS中JwtStrategy构造函数ConfigService注入未定义问题
NestJS中JwtStrategy构造函数里ConfigService为undefined的问题解决
问题描述
在jwt.strategy.ts的构造函数中,ConfigService始终返回undefined,只有在readonly configService: ConfigService前添加@Inject(ConfigService)装饰器才能解决该问题,但其他模块的依赖注入均正常工作。已尝试禁用其他模块、排查循环依赖,均无效果。
相关代码
AppModule
import configuration from './modules/config/configuration'; import { ConfigModule } from '@nestjs/config'; import { Module } from '@nestjs/common'; import { AuthModule } from './modules/auth/auth.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, load: [configuration], }), AuthModule, ], controllers: [], providers: [], }) export class AppModule { }
main.ts
import "reflect-metadata"; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ConfigService } from '@nestjs/config'; import { Logger } from '@nestjs/common'; async function bootstrap() { const logger = new Logger('Bootstrap'); const app = await NestFactory.create(AppModule); app.useLogger(logger); const configService = app.get(ConfigService); const port = configService.get<number>('port') || 4000; app.enableCors(); await app.listen(port); logger.log(`Server is running on http://localhost:${port}`); } bootstrap();
auth.module.ts
import { Module } from '@nestjs/common'; import { HashService } from '../common/hash.service'; import { AuthService } from './auth.service'; import { PassportModule } from '@nestjs/passport'; import { LocalStrategy } from './strategies/local.strategy'; import { JwtModule } from '@nestjs/jwt'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { JwtStrategy } from './strategies/jwt.strategy'; @Module({ imports: [ ConfigModule, PassportModule, JwtModule.registerAsync({ imports: [ConfigModule], inject: [ConfigService], useFactory: (configService: ConfigService) => ({ secret: configService.get<string>('jwtSecret'), signOptions: { expiresIn: '60m' }, }) }) ], providers: [AuthService, HashService, LocalStrategy, JwtStrategy], controllers: [], exports: [AuthService], }) export class AuthModule { }
原jwt.strategy.ts(存在问题)
import { ConfigService } from '@nestjs/config'; import { Injectable } from '@nestjs/common'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { JwtPayload } from '../jwt-payload.interface'; import { PassportStrategy } from '@nestjs/passport'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { constructor( readonly configService: ConfigService, ) { // here configService is undefined super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: configService.get<string>('jwtSecret') || '123', }); } async validate(payload: JwtPayload) { return payload; } }
原因分析
当类继承自第三方库的类(如这里的PassportStrategy)时,TypeScript的元数据收集可能出现异常。NestJS默认依赖装饰器和元数据实现自动注入,但继承链会干扰元数据的传递,导致Nest无法自动识别ConfigService的注入需求,必须显式通过@Inject装饰器声明依赖。
即使ConfigModule设置为全局模块,继承场景下的自动注入机制仍可能失效,显式注入是最可靠的解决方式。
解决方案
在JwtStrategy的构造函数参数中,为ConfigService添加@Inject(ConfigService)装饰器,修改后的代码如下:
import { ConfigService } from '@nestjs/config'; import { Inject, Injectable } from '@nestjs/common'; import { ExtractJwt, Strategy } from 'passport-jwt'; import { JwtPayload } from '../jwt-payload.interface'; import { PassportStrategy } from '@nestjs/passport'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { constructor( @Inject(ConfigService) readonly configService: ConfigService, ) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: configService.get<string>('jwtSecret') || '123', }); } async validate(payload: JwtPayload) { return payload; } }
额外检查项
确保tsconfig.json中开启了依赖注入必需的编译选项:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true } }
内容的提问来源于stack exchange,提问作者Тимофей Мелентьев
相关产品推荐
相关产品推荐

