NestJs - ConfigModule.forRoot isGlobal 不起作用

Sea*_*ean 6 nestjs dotenv nestjs-config

我试图在 AuthModule 中加载“process.env.AUTH_SECRET”,但它给了我未定义的错误“错误:secretOrPrivateKey 必须有一个值”。

我确实在 AppModule 中设置了“isGlobal: true”,并且它能够很好地读取“process.env.MONGO_URL”。

我还安装了 dotenv,如果我这样做的话,它读起来很好:

import * as dotenv from 'dotenv';
dotenv.config();

export const jwtConstants = {
  secret: process.env.AUTH_SECRET,
};

Run Code Online (Sandbox Code Playgroud)

但我宁愿以“NestJs”方式进行操作,因为文档说添加 isGlobal 应该使 env 可用于所有其他模块。

auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UserModule } from '../user/user.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { JwtModule } from '@nestjs/jwt';

@Module({
  imports: [
    UserModule,
    PassportModule,
    JwtModule.register({
      secret: process.env.AUTH_SECRET, //Cannot read this.
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService, JwtModule],
})
export class AuthModule {}

Run Code Online (Sandbox Code Playgroud)

应用程序模块.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule } from '@nestjs/config';
import { AuthModule } from './auth/auth.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    UserModule,
    MongooseModule.forRoot(process.env.MONGO_URL), // Can read this fine
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Run Code Online (Sandbox Code Playgroud)

我错过了什么或做错了什么?仅供参考,我正在尝试遵循此身份验证教程

谢谢你,

小智 16

你的MongooseModuleAuthModule依赖于你的ConfigModule,但他们不知道。

您的模块正忙于加载,但是您ConfigModule必须先执行异步 I/O 进程(读取您的 .env),然后才能准备好。同时,Nest 会继续加载,而不等待 ConfigModule 完成其工作,除非它发现另一个模块依赖于它的导出之一

这就是模块*异步风格的方法发挥作用的地方。它们使您可以控制模块实例化。ConfigService在这种情况下,它们允许我们从 中注入 ,在 准备好ConfigModule之前不会发生ConfigService

因此,将 JWTModule 配置从使用更改.register.registerAsync注入ConfigService就是您所追求的:

JWTModule.registerAsync({
    inject: [ConfigService],
    useFactory: (config: ConfigService) => {
      secret: config.get<string>('AUTH_SECRET'),
      signOptions: { expiresIn: '60s' }
    }
})
Run Code Online (Sandbox Code Playgroud)

现在,在 ConfigService 准备好并在范围内可用之前,JWTModule 不会加载。您很可能也需要为您的 MongooseModule 执行此操作。

这就是“NestJS”方式。

也就是说,如果您真正需要做的就是将 .env 加载到 process.env 中,请输入:

import * as dotenv from 'dotenv';
import { resolve } from 'path';
dotenv.config({ path: resolve(__dirname, '../.env') });
Run Code Online (Sandbox Code Playgroud)

在 main.ts 文件的开头。这将导致 dotenv 在发生其他事情之前同步加载它