포스트

대용량 파일 업로드를 위한 Presigned URL

Presigned URL이 필요한 이유

파일 업로드를 API 서버가 직접 중계하면 파일 크기가 커질수록 서버가 불필요한 병목이 된다. 네트워크 대역폭, 메모리, 타임아웃 관리 비용이 모두 서버 쪽으로 몰리기 때문이다.

Presigned URL은 서버가 스토리지 접근 권한만 짧게 위임하고, 실제 파일은 클라이언트가 스토리지로 직접 보내게 하는 방식이다. URL이 쓰는 권한은 URL을 만든 IAM 주체의 권한이다(S3 문서).

구조는 보통 다음과 같다.

  1. 클라이언트가 업로드 요청을 보낸다.
  2. 애플리케이션 서버가 업로드 대상과 만료 시간을 검토한다.
  3. 서버가 Presigned URL을 발급한다.
  4. 클라이언트가 그 URL로 스토리지에 직접 업로드한다.
  5. 서버는 메타데이터와 업로드 상태만 관리한다.

어떤 점이 좋은가

  • 서버가 파일 바이트를 중계하지 않는다.
  • 대용량 업로드에서 API 서버 부담이 크게 줄어든다.
  • 모바일, 브라우저, 외부 클라이언트에서도 구조가 단순하다.
  • 업로드 권한을 짧은 시간 동안만 제한적으로 위임할 수 있다.

설계할 때 중요한 포인트

1. 업로드 성공과 비즈니스 완료를 분리

S3 업로드가 성공했다고 해서 비즈니스적으로 “파일 등록 완료”라고 보면 안 된다. 바이러스 검사, MIME 검증, 메타데이터 저장, 후처리 큐 등록 같은 작업이 뒤따를 수 있다.

즉 업로드 완료와 도메인 처리 완료는 다른 상태로 관리하는 편이 안전하다.

2. 키를 클라이언트가 임의로 정하지 않게 하기

업로드 대상 키를 사용자가 자유롭게 정하게 두면 덮어쓰기, 경로 추측, 다중 테넌트 충돌 문제가 생길 수 있다. S3는 같은 키의 객체가 있으면 새 업로드로 교체하므로, 키가 겹치면 기존 파일이 사라진다. 보통은 서버가 키 규칙을 정하고 발급한다.

3. 만료 시간을 짧게 유지

S3 문서는 presigned URL을 “bearer tokens that grant access to those who possess them”이라고 설명한다(가진 사람이면 누구나 쓸 수 있다는 뜻). 만료 전까지는 여러 번 쓸 수도 있다. 그래서 URL은 짧게 발급할수록 안전하고, 업로드 권한은 오래 열어 둘 이유가 없다.

4. 대용량이면 multipart를 고려

파일이 커질수록 단일 PUT보다 multipart upload(파일을 파트로 나눠 올리고 S3가 합치는 방식)가 더 안정적이다. 실패한 파트만 다시 보내면 되므로 네트워크가 불안정할 때도 유리하다. S3 문서는 100MB 이상 객체에 이 방식을 권장한다(S3 문서).


자주 하는 실수

  • 업로드 URL만 발급하고 이후 검증 절차가 없다.
  • 파일 크기 제한, MIME 타입 제한, 확장자 정책이 없다.
  • 클라이언트가 원하는 경로로 아무 키나 업로드할 수 있다.
  • 서버가 실제 업로드 여부를 추적하지 않는다.

Presigned URL은 전송 경로를 서버 밖으로 옮길 뿐, 업로드 정책은 여전히 서버의 몫이다.


Presigned URL과 STS의 차이

Presigned URL은 특정 객체 요청 하나에 가까운 제한된 권한을 위임한다. 반면 STS 임시 자격 증명은 더 넓은 권한 범위를 일정 시간 부여하는 방식이다.

일반적인 웹 업로드에서는 Presigned URL이 단순하고 통제하기 쉽다. 여러 객체 조작이나 SDK 기반 복합 작업이 필요할 때는 STS가 더 맞을 수 있다.


정리

서버는 파일 바이트를 다루지 않는 대신 두 가지를 챙긴다. URL이 bearer token이므로 키와 만료를 서버가 정하고, 업로드 성공이 도메인 완료가 아니므로 이후 상태를 서버가 추적한다.

참고한 자료외부 출처 2

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다