Presigned URL로 파일 업로드하기

dasd412·2024년 12월 30일
0

실무 문제 해결

목록 보기
15/17

문제 상황

파일 업로드를 하기 위해 graphql로 업로드하는 로직을 연구하고 있었다. 해당 로직은 예제를 참고해서 완성했고, 서버에서 API가 정상 작동함을 확인하였다.

하지만, 서버 앞 단의 미들웨어가 문제였다.
Mesh Gateway라는 미들웨어인데, MSA 서버들의 데이터 소스를 graphql 스키마로 변환 및 통합한다. 프론트엔드는 해당 미들웨어에 대한 URL만 알면 된다.

Mesh Gateway를 경유해서 파일 업로드 API 요청을 하면, 미들웨어가 버전이 너무 낮아 작동하지 않는 것을 발견했다.

해당 미들웨어를 뜯어내고 다른 걸로 교체하는 것은 백엔드와 인프라에 너무 많은 작업 시간을 소요하는 작업이었다.

그래서 다른 방법을 찾게 되었다.


Presigned URL 채택

Presigned URL은 서버를 통해 파일 업로드를 하지 않고, 클라이언트가 클라우드 스토리지 서비스에 직접 업로드할 수 있도록 인증된 URL을 제공하는 방식이다.

URL이라는 String 값을 프론트엔드에게 주기만 하면 되므로, 미들웨어 문제가 발생하지 않으면서 파일을 업로드할 수 있었다.

작동 방식

  1. 클라이언트가 서버에게 파일 업로드를 요청한다. 파일 이름, 파일 크기 및 이름, MIME 타입, 파일 해시값, 그 외 메타데이터 정보가 포함된다.
  2. 클라이언트가 보낸 요청에 대해 서버가 유효성을 검증한다.
  3. 서버가 클라우드 스토리지 서비스와 통신해서 Presigned URL을 생성한 후, 클라이언트에게 제공한다.
  4. 클라이언트는 제공받은 Presigned URL을 사용해서 클라우드 스토리지 서비스에 직접 업로드한다.

장점

  1. 서버 부하가 감소한다. 왜냐하면 서버가 직접 클라우드 스토리지 서비스에 전달하는 과정이 생략되기 때문이다. 네트워크 대역폭도 줄일 수 있다.
  2. Presigned URL은 제한된 기간 동안만 유효하기 때문에 보안이 우수하다. JWT Refresh 토큰과 같은 느낌이다.

단점

  1. Presigned URL이 노출되면, URL 유효 기간동안 누구나 해당 URL에 접근할 수 있으므로 보안 위험 요소가 있다. 따라서 유효 기간을 짧게 설정해야 한다.
  2. 프론트엔드 개발자의 추가 작업이 필요하다. S3에 실제로 업로드하는 책임은 프론트엔드 개발자로 옮겨졌기 때문...

더 나아가기

1. 사후 검증 로직 추가

Presigned URL을 생성하기 전에 클라이언트 파일이 업로드 조건을 충족하는 지에 대해 사전 검증을 수행하긴 하지만, 이것만으로는 부족하다.

왜냐하면 사전 검증 요청에 포함된 파일 정보 등이 조작될 가능성도 있기 때문이다.

따라서 파일이 실제로 업로드된 뒤에, 서버가 해당 파일을 검증하는 사후 검증 로직도 필요하다.

  1. 사전 검증에서 보낸 파일 메타데이터가 일치하는지
  2. 사전에 제공받은 파일 해시값이 일치하는지(같은 파일을 같은 해싱 알고리즘으로 처리하면 항상 동일한 해시값이 나옴을 이용한다.)
  3. 기타 보안에 문제가 없는지 검증

2. CDN 사용하기

S3에 업로드되는 파일 중, 이미지나 동영상 같은 파일들은 추후 사용자에게 보여질 필요도 있다.

이런 대용량 정적 콘텐츠 배포에는 CDN을 사용하면, 사용자에게 더 빨리 콘텐츠를 제공할 수 있을 것이다.


profile
시스템 아키텍쳐 설계에 관심이 많은 백엔드 개발자입니다. (Go/Python/MSA/graphql/Spring)

0개의 댓글