registerAs()란?
NestJS에서 설정 객체를 모듈화하여 ConfigModule에서 쉽게 가져올 수 있도록 도와주는 함수
여러 개의 설정 파일을 만들고 ConfigModule에서 불러올 때 Key를 기반으로 접근할 수 있도록 한다.
// jwt.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('jwt', () => ({
secret: process.env.JWT_SECRET || 'default-secret', // JWT 서명 키
signOptions: {
expiresIn: process.env.JWT_EXPIRES_IN || '1h', // JWT 만료 시간
},
}));
TypeScript
복사
‘jwt’라는 key를 설정했으므로 ‘jwt’라는 네임스페이스를 가진 설정 객체가 된다. → jwtConfig로 접근 가능!
app.module.ts에서 configModule.forRoot()의 load 옵션을 사용하여 위 설정 파일을 불러온다.
// src/app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import jwtConfig from './config/jwt.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true, // 글로벌 모듈로 등록
load: [jwtConfig], // jwt 설정 파일 로드
}),
],
})
export class AppModule {}
TypeScript
복사
새로운 사실
위에서 key값을 설정하면 key값이 네임스페이스로 설정된 설정 객체가 된다고 했다.
ex) ‘abc’ → abcConfig로 접근가능
import jwtAuthConfig from '@/common/config/auth/jwt.auth.config';
@Inject(jwtAuthConfig.KEY)
private jwtTokenConfig: ConfigType<typeof jwtAuthConfig>,
----------------------------------------------------------------------------------------------------------
import jwtConfig from '../../config/auth/jwt.auth.config';
@Inject(jwtConfig.KEY)
private jwtConfiguration: ConfigType<typeof jwtConfig>,
// ConfigType<typeof xxxConfig>로 타입 안정성을 유지하면서 설정을 가져올 수 있다.
TypeScript
복사
그러나 위와같은 문법을 사용하게 되면 key값과 동일한 이름으로 config를 잡지않아도 import로 매핑을 시키면 key값과 다른 이름으로도 설정이 가능하다….
위 두 케이스에서는 서로 다른이름으로 config를 설정하였지만 둘 다 ‘jwt’를 키값으로 설정한 config파일과 연동되어 있다….
jwt 모듈 등록
@Module({
imports: [
JwtModule.register({
secret: process.env.JWT_SECRET,
signOptions: { expiresIn: '12h' },
}),
HttpModule,
PassportModule, // 기본 설정만 등록, 전략은 각별히 등록
],
}),
exports: [JwtModule],
export class AuthModule {}
TypeScript
복사
위와 같은 방법으로 Jwt모듈을 등록할 수 있다.
하지만 나는 jwtConfig라는 설정 객체를 만들어서 모듈화를 해뒀다.
그렇다면 이렇게 코드를 짤 수도 있다.
@Module({
imports: [
JwtModule.registerAsync(jwtConfig.asProvider()),
ConfigModule.forFeature(jwtConfig),
HttpModule,
PassportModule,
],
exports: [JwtModule],
})
export class AuthModule {}
// jwt.config.ts
export default registerAs(
'jwt',
(): JwtModuleOptions => ({
secret: process.env.JWT_SECRET,
signOptions: {
expiresIn: process.env.JWT_EXPIRE_IN,
},
}),
);
TypeScript
복사
•
jwtModule.registerAsync(jwtConfig.asProvider())
NestJS에서 JwtModule.register() 를 사용할수도 있지만 환경변수나 설정파일에서 값을 가져와야 하는 경우 비동기 설정방식인 registerAsync()를 사용한다.
◦
비동기설정
동기적인 방식(static)이 아니라 실행 시점에 동적으로 값을 가져올 수 있도록 한다.
1.
정적 설정 (static)
JwtModule.register({
secret: 'mysecret',
signOptions: { expiresIn: '12h' },
});
장점 : 간단하고 빠르다.
단점 : 환경 변수 또는 외부 시스템에서 값을 가져올 수 없다.
TypeScript
복사
2.
동적 설정 : 실행 시점에 값을 로드할 수 있지만, 비동기 작업은 불가능한 방식
JwtModule.register({
secret: process.env.JWT_SECRET || 'default-secret',
signOptions: { expiresIn: process.env.JWT_EXPIRE_IN || '12h' },
});
장점 : 환경 변수 등 동적으로 값을 설정 가능
단점 : DB 조회나 API 호출처럼 비동기 작업을 수행할 수 없다.
TypeScript
복사
3.
비동기 설정
JwtModule.registerAsync({
imports: [ConfigModule], // ConfigService 사용 가능하도록 설정
inject: [ConfigService], // ConfigService를 주입받음
useFactory: async (configService: ConfigService) => ({
secret: await someAsyncFunction(configService.get('JWT_SECRET')),
signOptions: { expiresIn: configService.get('JWT_EXPIRE_IN') || '12h' },
}),
});
장점 : DB 조회나 API 호출처럼 비동기 작업을 수행할 수 있다.
단점 : 코드가 복잡해짐.
TypeScript
복사
◦
jwtConfig.asProvider()
jwt.config.ts에서 registerAs()로 만든 설정을 jwtModule.registerAsync() 에서 사용할 수 있도록 변환하는 함수
registerAs()는 일반적으로 ConfigModule.forFeature()와 함께 사용되지만 asProvider()를 사용하면 해당 설정을 직접 JWT 모듈의 프로바이더로 사용할 수 있다.
export default registerAs(
'jwt',
() => ({
secret: process.env.JWT_SECRET,
signOptions: { expiresIn: process.env.JWT_EXPIRE_IN || '12h' },
}),
);
// `asProvider()`를 사용하면 위 설정을 JwtModule에 직접 넘길 수 있음
// 아래 코드는 위 코드와 동일하게 동작한다.
JwtModule.registerAsync(jwtConfig.asProvider()),
TypeScript
복사