Nest.js의 ConfigModule은 env 파일을 dotenv를 사용하지 않고 모듈화하여 유연하게 사용할 수 있게 해준다.
다만 Nest.js의 Module 이외에는 사용이 불가능하다.
ConfigModule 사용 시 ConfigService를 주입해서 사용해야 함
Nestjs에서 JWT를 사용해 토큰을 발급해줘야 할 일이 있었는데
JWT의 secret_key를 .env 파일에 정의해뒀다.
하지만 지속적으로 401에러나 secretOrPrivateKey must have a value라는 에러가 떴다.
.env파일을 읽어오지 못하는 에러라서 dotenv랑 cross-env도 깔아봤는데 별다른 소용이 없었다.
원래 app.module.ts의 코드는 다음과 같다.
@Module({
imports: [
TypeOrmModule.forFeature([User]),
JwtModule.register({
secret: process.env.SECRET_KEY,
signOptions: { expiresIn: '60s' },
}),
],
exports: [TypeOrmModule],
controllers: [AuthController],
providers: [
AuthService,
UserService,
LocalStrategy,
JwtStrategy,
RefreshJwtStrategy,
],
})
export class AuthModule {}
이 벨로그를 보면 처음부터 import를 해두지만 .env를 읽어오는 작업은 비동기적이기 때문에 로 인해 JwtModule.register에서 process.env.JWT_SECRET을 참조할 때까지 .env를 다 못 읽어오는 일이 발생한다고 한다.
이에 대한 해답은 JwtModule의 registerAsync를 사용하는 것이다.
ConfigService를 주입해두면 .env를 읽어올 때까지 secret을 등록하는 작업을 유예시킬 수 있다.
@Module({
imports: [
TypeOrmModule.forFeature([User]),
JwtModule.registerAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
secret: config.get<string>('SECRET_KEY'),
signOptions: { expiresIn: '60s' },
}),
}),
],
exports: [TypeOrmModule],
controllers: [AuthController],
providers: [
AuthService,
UserService,
LocalStrategy,
JwtStrategy,
RefreshJwtStrategy,
],
})
ConfigModule.forRoot({ isGlobal: true })처럼 isGlobal 옵션을 true로 바꿔주면 정상적으로 작동된다!!
require('dotenv').config()를 사용했을 때도 .env파일이 인식되긴 했는데 기왕이면 nest에서 권장하는 방식대로 하는게 맞다고 생각이 들어 ConfigModule을 최대한 활용하고 싶었다!