안녕하세요! 오늘은 NestJS로 개발하시는 분들이 한 번쯤은 마주치셨을 법한 JWT 관련 에러를 함께 파헤쳐보려고 합니다. 특히 'secretOrPrivateKey must have value' 에러는 개발자들의 골치를 아프게 하는 대표적인 문제인데요, 이 에러의 발생 원인과 해결 방법을 상황별로 정리해보았습니다.
## 🤔 에러가 발생하는 근본적인 이유
이 에러의 핵심은 간단합니다. JWT를 sign할 때 사용하는 secret 값과 설정된 secret 값이 일치하지 않는 거죠. 특히 ConfigModule을 사용할 때 환경 변수를 불러오는 과정에서 가장 빈번하게 발생합니다.
## 📌 주요 발생 케이스와 해결방법
### 1. 환경변수 설정 미스 (가장 흔한 케이스)
개발하다 보면 `.env` 파일은 만들었는데, ConfigModule 설정을 깜빡하는 경우가 있습니다.
```typescript
// ❌ 이렇게 하면 안 됩니다!
@Module({
imports: [
JwtModule.register({
secret: process.env.JWT_SECRET, // undefined가 될 수 있어요!
signOptions: { expiresIn: '60s' },
}),
],
})
// ✅ 이렇게 해주세요!
@Module({
imports: [
ConfigModule.forRoot(), // 잊지 마세요!
JwtModule.register({
secret: process.env.JWT_SECRET,
signOptions: { expiresIn: '60s' },
}),
],
})
2. 비동기 설정 처리 실수 🕒
가끔 동적으로 secret을 가져와야 하는 경우가 있죠? 이때는 registerAsync
를 사용해야 합니다.
// ✨ 비동기 처리는 이렇게!
@Module({
imports: [
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get('JWT_SECRET'),
signOptions: { expiresIn: '60s' },
}),
inject: [ConfigService],
}),
],
})
💡 실제 개발 시 유용한 팁들
1. 환경변수 유효성 검사 추가하기
// app.module.ts
@Module({
imports: [
ConfigModule.forRoot({
validationSchema: Joi.object({
JWT_SECRET: Joi.string().required(),
}),
}),
],
})
이렇게 하면 앱이 시작될 때 환경변수가 제대로 설정되었는지 확인할 수 있습니다!
2. 디버깅을 위한 로깅 추가
// auth.service.ts
constructor(
private configService: ConfigService,
private logger: Logger
) {
const secret = this.configService.get('JWT_SECRET');
if (!secret) {
this.logger.error('🚨 JWT_SECRET이 설정되지 않았습니다!');
throw new Error('JWT 설정 에러');
}
}
🚀 실전 문제 해결 체크리스트
.env
파일이 프로젝트 루트에 있나요?ConfigModule.forRoot()
가 제대로 설정되어 있나요?- Docker를 사용한다면 환경변수가 제대로 전달되고 있나요?
- 테스트 환경에서도 JWT_SECRET이 설정되어 있나요?
마치며 ✍️
JWT 관련 에러는 대부분 설정 과정에서 발생하는 경우가 많습니다. 특히 secret 값을 다루는 부분은 신중하게 확인해야 하죠. 위의 체크리스트를 따라가면서 확인하시면, 대부분의 문제는 해결될 거예요!
혹시 이 글을 보시고도 해결되지 않는 문제가 있다면, 댓글로 남겨주세요. 함께 고민해보고 해결방법을 찾아보면 좋겠습니다. 😊
다음에는 NestJS의 또 다른 흥미로운 주제로 찾아뵙겠습니다!
참고: 이 글의 예제 코드는 NestJS v9.0.0 이상을 기준으로 작성되었습니다.
'개발 > NestJS' 카테고리의 다른 글
JavaScript/TypeScript의 for...of와 for await...of 완벽 가이드 (0) | 2024.11.27 |
---|---|
[NestJS] Queue 완벽 가이드: 기초 개념부터 실전 활용까지 (0) | 2024.11.25 |
TypeORM에서 insert() 사용 시 @BeforeInsert가 동작하지 않는 문제 해결하기 🤔 (0) | 2024.11.20 |
NestJS 설정 관리의 진화: nestjs-library-config 도입기 (4) | 2024.11.18 |
NestJS에서 AWS S3 파일 업로드 깔끔하게 구현하기 🚀 (0) | 2024.11.15 |
댓글