NestJS Guard에서 multipart/form-data 처리하는 법 – 왜 request.body가 비어있을까?

som·2024년 8월 8일
0

NestJS

목록 보기
1/2

NestJS에서 권한을 세분화하여 관리하는 과정에서 multipart/form-data 형식의 요청을 처리하는 데 문제가 발생했습니다. 이 글에서는 해당 문제를 해결한 과정을 정리해보았습니다.


1. 문제 상황

저희 애플리케이션은 다음과 같이 각 기능마다 다른 권한을 요구합니다.

  • 매니저만 공지사항 등록 가능
  • 커뮤니티 유저만 커뮤니티 게시글 등록 가능
  • 일반 유저가 볼 수 있는 라이브 방송 기능 제공

이처럼 기능별로 권한이 다르기 때문에, 요청마다 권한을 검증하는 과정이 필요했습니다.

기존 문제점

  1. 권한 검사 로직 중복
    • 서비스 레이어에서 개별적으로 검사하여 코드 중복 발생
  2. 보안 취약점
    • 서비스 레이어까지 불필요한 요청이 도달하여 민감한 데이터 접근 가능
  3. 불필요한 리소스 소비
    • 권한이 없는 요청도 내부 로직 실행 → 성능 저하 유발
  4. 권한 관리의 일관성 부족
    • 일부는 Guard, 일부는 서비스에서 검사하여 유지보수 어려움
  5. 확장성과 유지보수성 저하
    • 권한 정책 변경 시 여러 서비스 코드 수정 필요

처음에는 일반 유저만 가드를 적용하고, 커뮤니티 유저와 관련된 권한은 서비스 레이어에서 검사했습니다. 그러나 이 방식은 코드 중복을 유발했고, 권한이 없는 사용자가 서비스 로직까지 도달하여 보안 이슈가 발생할 가능성이 있었습니다.


2. 해결 방법: Guard 적용

이러한 문제를 해결하기 위해 NestJS의 Guard 기능을 활용했습니다. Guard는 NestJS에서 제공하는 공식적인 인증 및 권한 관리 기능이고, AuthGuard와 함께 사용하면 사용자 인증을 쉽게 처리할 수 있다고 생각했습니다.

✅ Guard 적용 예상 결과 & 결론

  1. 중복된 권한 검사 로직 제거
    • Guard에서 권한 검사를 수행 → 서비스 레이어는 비즈니스 로직에만 집중 가능
  2. 보안 강화 및 불필요한 요청 차단
    • 서비스 진입 전에 차단하여 민감한 데이터 보호 및 성능 최적화
  3. 일관된 권한 관리
    • 모든 API에 동일한 방식으로 Guard 적용 → 접근 제어 정책 유지
  4. 유저 권한 정보 제공
    • Guard에서 매니저, 아티스트 등의 권한 정보를 서비스로 전달하여 중복 코드 감소
  5. 확장성과 유지보수성 개선
    • 새로운 권한 정책 추가 시 Guard만 수정하면 적용 가능 → 서비스 코드 수정 최소화

결론: Guard를 활용하여 서비스 로직을 간결하게 유지하면서 보안과 성능을 개선하고, 유지보수성을 향상시킬 수 있었습니다.


3. 해결 방법 적용 후 발생한 문제

Guard를 적용하는 과정에서 또 다른 문제가 발생했습니다.

❌ 문제점: multipart/form-data 요청 처리 이슈

게시글을 등록하는 API에서는 JSON 형식의 게시글 정보와 함께 이미지 파일을 업로드할 수 있도록 multipart/form-data를 사용하고 있습니다.

하지만, Guard에서 multipart/form-data 형식의 request.body 값을 읽을 수 없는 문제가 발생했습니다.

원인 분석

multipart/form-data 요청은 파일 인터셉터를 사용해 파일 업로드가 완료된 후 request.filesrequest.body로 분리됩니다. 이 분리 시점이 Guard보다 늦게 실행되어 request.body를 찾을 수 없었던 것 입니다.


4. 해결 방법: 미들웨어 적용

이 문제를 해결하기 위해 Guard 이전 단계에서 실행되는 미들웨어를 활용했습니다.

✅ 적용 방법

  1. Multer 미들웨어를 게시글 모듈에 적용하여 파일을 먼저 처리
  2. 파일 업로드 완료 후 filesbody가 분리됨
  3. Guard에서 분리된 body 값을 받아와 유저 권한 확인

이 방법을 통해 Guard에서도 request.body 값을 정상적으로 확인할 수 있었습니다.


5. 결론 및 개인적인 생각

이번 해결 방법은 완벽하지 않지만, NestJS의 라이프사이클을 고려하여 Guard와 multipart/form-data 요청을 함께 사용하는 방법을 고민해본 사례로 기록하고자 합니다.

혹시 같은 문제를 겪고 계신 분들에게 도움이 되었으면 좋겠습니다. 😊


📌 참고 자료

profile
개인 기록용 블로그

0개의 댓글