프로젝트를 진행하며 이미지를 업로드하는 기능을 구현해야 했다. 이미지 관련 로딩 시간을 줄여 사용자 경험을 개선할 수 있는 방법을 모색하던 중 서버에서 이미지 업로드와 관련하여 새로운 api 통신 방식을 제안했다!
이미지가 주가 되는 서비스인 만큼 이미지 로딩 시간을 최대한 감소
시키기 위해 고민하던 내게, 이미지 용량 및 로딩 시간 이슈 모두 해결할 수 있는 방식이라니..!! 당장 구현해보고 싶었다.
서버 측과 이야기한 방식은 바로 바로 Presigned Url
!! 이었다.
S3 Presigned URL은 S3의 Bucket Policy나 acl과 같은 권한 설정과 관계없이 특정 유효기간동안 S3에 get, put을 가능하게 하는 url이다. 간단히 말하자면 클라이언트에서 S3에 사진을 올릴 수 있고, 이 주소를 통해 해당 이미지에 접근이 가능하다는 것이다.
일반적으로 구현하는 이미지 업로드 방식은 multipart/form-data 방식으로, 이미지 관련 API 호출 시 실제 이미지를 서버로 보내준다. 결론적으로 클라이언트와 서버가 직접 통신하는 방식이라고 할 수 있다.
multipart/form-data 방식으로 e-commerce 서비스를 구현했던 경험이 있다. 이 방식으로 상품 관련 이미지를 불러왔고 홈 화면에 mp4까지 띄워줬더니, 서비스가 굉장히 무거워지는 걸 느낄 수 있었다. (홈 화면 로딩과, 서비스 배포 모두 오랜 시간이 걸림)
그에 반해 Presigned Url 방식을 사용하면 이미지를 서버에 그대로 넘기는 것이 아니라, 클라이언트가 S3에 직접 업로드 한 뒤 해당 주소를 서버에 넘기기 때문에 이미지를 불러오는 속도가 빨라진다는 것을 알 수 있었다!
이쯤에서 ‘단순히 속도 향상때문에 Presigned URL을 사용하는 것이라면, 클라이언트가 S3에 직접 이미지를 업로드하면 될 일 아닌가?’ 라는 생각이 들었다. 어차피 클라이언트가 S3에 접근하는 것 같은데, 그럴거면 클라이언트 측에서 직접 업로드하는 방식이랑 다를게 뭐야!! 이런 생각도 잠시, 금방 해답을 찾을 수 있었다.
Presigned URL로 이미지를 업로드하게 되면 서버 측에서 검증해준 url로 업로드를 할 수 있다. 즉, 언제 어디서 어떤 사용자가 이미지를 업로드하더라도 검증된 url로 업로드가 가능하다는 이야기이다.
이외에도 제한 시간 설정과 확장자 검증 또한 가능하기 때문에, 클라이언트 측에서 업로드하는 것보다 훨씬 보안성이 강화된다.