You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Тимофей Мелентьев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:08:16