Search

[AWS] S3 PreSignedURL 이해하기

글감
인프라
AWS
S3
PreSignedURL
작성자
작성 일자
2025/04/19 11:10
상태
완료
공개여부
공개
Date
2025/04/19
생성자
작업자

개요

multipart/form-data 형식에 헤더를 사용하여 이미지 파일을 직접 애플리케이션 서버로 보내고, 애플리케이션 서버에서 스토리지 저장소에 업로드하는 방식이, 이미지 파일을 업로드하는 API에서 생각할 수 있는 일반적인 구조일 거에요.
하지만 이런 구조에서는 이미지 파일은 일반적으로 용량이 크기 때문에 이로 인해 애플리케이션 서버의 부하가 늘어날 거에요.
이런 문제는 소식지 생성/수정 같은 게시글 생성 API에서 더욱 두드러져요. 이런 게시글 생성 API의 경우 이미지를 여러 장 선택하고, 들어가는 텍스트의 길이도 굉장히 길 것이에요. 그런데 이런 많은 내용들이 게시글 생성 버튼을 눌렀을 때 한 번에 전송될거에요. 그 순간 서버에 가해지는 부하는 상당하겠죠..?

PreSigned URL로 해결!

이런 부하를 개선할 수 있는 방법이 바로 PreSigned URL이에요. 클라이언트가 직접 S3와 같은 파일 스토리지에 올릴 수 있는 권한을 일시적으로 제공하는 방식이죠!
대략적인 플로우는 다음과 같아요.
1.
먼저 클라이언트는 애플리케이션 서버에 S3에 올리고 싶은 경로를 담아 요청해요. (토큰이든 세션이든 자체적으로 인증은 있어야겠죠?)
→ 그림은 avatar-images/random-string/avatar.png 라는 경로로 이미지를 업로드하고 싶은 상황이에요.
2.
애플리케이션 서버에서는 해당 경로로 이미지를 업로드할 수 있는 인증코드가 query string에 담긴 PreSigned URL을 응답해요.
3.
클라이언트는 PreSigned URL에 이미지 파일을 담아 PUT으로 업로드 요청을 보내요.
4.
S3 파일 스토리지는 해당 경로에 이미지를 업로드하고 성공 응답을 제공해줘요.

PreSigned URL 발급 및 이미지 업로드

그렇다면 실제로 PreSigned URL을 발급받아 해당 경로에 이미지를 업로드 해봅시다!
(서버쪽 코드는 생략할게요..!)
먼저 애플리케이션 서버에서 PreSigned URL을 발급할 수 있는 엔드포인트를 제공해줍니다.
클라이언트는 Request Body로 업로드하고 싶은 경로를 적어주어요.
(random-string 부분에는 UUID등을 이용하여 랜덤으로 생성된 문자열을 넣어주어야 해요!)
이런 요청을 보내주면
이렇게 PreSigned URL이 발행돼요!
Credential= … 라고 되어 있는 부분이 유효한 인증인지 검증하기 위해서 사용될거에요.
이후에는 간단해요. 클라이언트 측에서 해당 URL에 이미지 파일을 Body에 담아서 PUT 요청을 보내면 끝입니다!
curl & javascript 요청 예시
200 OK를 응답받으면 성공이에요!
해당 링크를 열어보면 방금 업로드한 이미지를 확인할 수 있어요!
관련 서버쪽 구현이 궁금하시다면 다음 링크를 참고해주세요!