users 를 불러와보면 위와 같이 password가 그대로 노출된다.
물론 패스워드가 암호화되어있지만 이러한 민감한 정보를 클라이언트에서 노출하는 것 자체가 보안에 민감한 사항이다.
Intercepter와 ClassSerializerInterceptor
Interceptor
Interceptor는 컨트롤러의 핸들러가 실행되기 전이나 후에 코드를 실행할 수 있다. 이를 통해 공통 로직(예: 로깅, 캐싱, 응답 포맷팅, 예외 처리 등)을 중앙에서 처리할 수 있다.
ClassSerializerInterceptor
ClassSerializerInterceptor는 class-transformer를 기반으로 동작하여, 컨트롤러에서 반환된 객체를 자동으로 직렬화(serialize)해준다.
이때, 클래스에 적용된 @Exclude(), @Expose(), @Transform() 등의 데코레이터를 활용해 응답 데이터의 형식을 변환한다.
Password 제외해보기
@Get()
@UseInterceptors(ClassSerializerInterceptor)
getUsers() {
return this.usersService.getAllUsers();
}
유저들을 가져오는 라우터에 위와 같은 데코레이터를 적용한다.
@Exclude
제외할 컬럼을 지정할 수 있다.
@Exclude({
toPlainOnly: true,
})
password: string;
UsersModel 의 password에 적용한다.
@Exclude 옵션
toClassOnly
- class instance로 변환될때만 제외되도록 한다.
- 요청인 경우에 제외
- 클라이언트 -> 서버
toPlainOnly
- plain object로 변환될때만 제외되도록 한다.
- 응답인 경우에 제외
- 서버 -> 클라이언트
위의 경우 비밀번호는 클라이언트에서 받아야하므로 toClassOnly는 false이고,
반대로 비밀번호는 응답에 클라이언트에 노출되지 않아야하므로 toPlainOnly는 true이다.
이전과 다르게 password가 노출되지 않는다.
글로벌하게 적용하기
@UseInterceptors(ClassSerializerInterceptor) 의 문제점은 위와 같이 모든 클래스에 적용되지 않는다는 점이다.
그러므로 일일이 필요한 라우터에가서 지정해줘야 한다.
providers: [AppService, {
provide: APP_INTERCEPTOR,
useClass: ClassSerializerInterceptor,
}],
이를 해결하기 위해선 모든 클래스에 적용되도록 해야하는데, app.module.ts 의 providers 부분을 위와 같이 수정한다.
위와 같이 모든 UsersModel의 password는 제외된 것을 볼 수 있다.
'NestJS' 카테고리의 다른 글
NestJS - Pagination 심화 (일반화하기) (0) | 2025.03.05 |
---|---|
NetJS - Pagination 기본 (0) | 2025.03.02 |
NestJS - Class Validation과 DTO (0) | 2025.02.28 |
Postman 심화기능 (0) | 2025.02.27 |
NestJS - Custom Decorator (0) | 2025.02.27 |