요즘 nestJS 공부 중이다~~
access token을 발급하는 중에 .env에 있는 JWT_SECRET을 읽어오지 못해서 오류가 났다.
jwt secretorprivatekey must have a value 😈
처음에는 공식문서대로 JwtModule.register를 사용했는데,
@Module({
imports: [
UsersModule,
JwtModule.register({
global: true,
secret: process.env.JWT_SECRET,
signOptions: { expiresIn: '60s' },
}),
],
providers: [AuthService],
controllers: [AuthController],
exports: [AuthService],
})
export class AuthModule {}
auth.controller.ts에서 log로는 찍히고 register는 안되는 신기한 현상이 일어났다.
JWT_SECRET을 등록할 때 환경변수를 사용하지 않을거면 문제 없다. 검색해보니 .env를 비동기적으로 읽어오기 때문에 환경변수를 읽어오기도 전에 JwtModule에 register가 되어서 undefined가 찍힐 수도 있다고 한다.
먼저 app.module.ts에서 ConfigModule.forRoot()를 import해주고, isGlobal: true로 지정하여 전역에서 사용할 수 있도록 한다.
@Module({
imports: [
AuthModule,
UsersModule,
ConfigModule.forRoot({
isGlobal: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
다음으로 auth.module.ts에서 JwtModule.rgister 대신 아래와 같이 동적 모듈인 registerAsync를 이용한다.
✏️ 정적 모듈 vs 동적 모듈
동적 모듈의 경우 설정 값과 의존성을 런타임에 주입한다. 반면 정적 모듈의 경우에는 설정 값과 의존성을 컴파일 시점에 주입한다. registerAsync의 경우에는 ConfigService라는 의존성과 환경 변수 설정값들을 런타임에 주입하며, 환경 변수를 읽어올 때까지 주입을 지연시킬 수 있는 것이다.
nest에서 제공해주는 ConfigService를 inject해서 사용해야 한다.
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { UsersModule } from 'src/users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
@Module({
imports: [
UsersModule,
JwtModule.registerAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
secret: config.get<string>('JWT_SECRET'),
signOptions: { expiresIn: '60s' },
}),
}),
],
controllers: [AuthController],
providers: [AuthService],
})
export class AuthModule {}
참고: https://velog.io/@daep93/Nestjs-secretOrPrivateKey-must-have-a-value