📸 새로운 이미지 업로드 방식

프로젝트를 진행하며 이미지를 업로드하는 기능을 구현해야 했다. 이미지 관련 로딩 시간을 줄여 사용자 경험을 개선할 수 있는 방법을 모색하던 중 서버에서 이미지 업로드와 관련하여 새로운 api 통신 방식을 제안했다!

이미지가 주가 되는 서비스인 만큼 이미지 로딩 시간을 최대한 감소시키기 위해 고민하던 내게, 이미지 용량 및 로딩 시간 이슈 모두 해결할 수 있는 방식이라니..!! 당장 구현해보고 싶었다.

서버 측과 이야기한 방식은 바로 바로 Presigned Url!! 이었다.

📸 Presigned URL이란?

S3 Presigned URL은 S3의 Bucket Policy나 acl과 같은 권한 설정과 관계없이 특정 유효기간동안 S3에 get, put을 가능하게 하는 url이다. 간단히 말하자면 클라이언트에서 S3에 사진을 올릴 수 있고, 이 주소를 통해 해당 이미지에 접근이 가능하다는 것이다.

일반적으로 구현하는 이미지 업로드 방식은 multipart/form-data 방식으로, 이미지 관련 API 호출 시 실제 이미지를 서버로 보내준다. 결론적으로 클라이언트와 서버가 직접 통신하는 방식이라고 할 수 있다.

Untitled

multipart/form-data 방식으로 e-commerce 서비스를 구현했던 경험이 있다. 이 방식으로 상품 관련 이미지를 불러왔고 홈 화면에 mp4까지 띄워줬더니, 서비스가 굉장히 무거워지는 걸 느낄 수 있었다. (홈 화면 로딩과, 서비스 배포 모두 오랜 시간이 걸림)

그에 반해 Presigned Url 방식을 사용하면 이미지를 서버에 그대로 넘기는 것이 아니라, 클라이언트가 S3에 직접 업로드 한 뒤 해당 주소를 서버에 넘기기 때문에 이미지를 불러오는 속도가 빨라진다는 것을 알 수 있었다!

⁉️ 여기서 잠깐! 그럼 클라이언트에서 직접 업로드하면 되는 거 아니야?

이쯤에서 ‘단순히 속도 향상때문에 Presigned URL을 사용하는 것이라면, 클라이언트가 직접 이미지를 업로드하면 될 일 아닌가?’ 라는 생각이 들었다. 어차피 클라이언트가 S3에 접근하는 것 같은데, 그럴거면 클라이언트 측에서 직접 업로드하는 방식이랑 다를게 뭐야!! 이런 생각도 잠시, 금방 해답을 찾을 수 있었다.

Presigned URL로 이미지를 업로드하게 되면 서버 측에서 검증해준 url로 업로드를 할 수 있다. 즉, 언제 어디서 어떤 사용자가 이미지를 업로드하더라도 검증된 url로 업로드가 가능하다는 이야기이다.

이외에도 제한 시간 설정과 확장자 검증 또한 가능하기 때문에, 클라이언트 측에서 업로드하는 것보다 훨씬 보안성이 강화된다.