Amazon S3

1. KEY의 특수 문자 문제 - signaturedoesnotmatch

아마존 Presinged URL을 발급하기 위해서는 권한을 인증받을 KEY가 필요합니다. 발급받은 KEY에 +, -, /, % 등의 특수 문자가 있다면 prsinged URL이 받아지지만 해당 URL로 요청을 보내면 400 에러와 함께 signaturedoesnotmatch라는 오류가 발생할 수 있습니다. 해당 문자가 없는 KEY를 발급 받을 때까지 재발급 받아 해결하였습니다.

2. 만료시간 - ExpiredToken

백서버에서 Presinged URL을 아마존 S3로 보내고 받을 URL로 즉시 사진을 업로드 하였음에도 불구하고 계속 만료 시간이라는 메세지를 받았습니다. 만료 시간을 현재  UTC를 기준으로 15분을 추가하였기 때문에 발생한 문제였습니다. 아마존 S3서버의 Region이 서울이었기에 현재 시간을 서울의 시간으로 바꾼 뒤 15분 뒤를 만료시간으로 설정하여 해결하였습니다. 참고로 AWS SDK를 사용하여 만료시간은 최장 7일까지 가능합니다.

3. 빈 파일이 업로드 됩니다. - Content-type

프론트에서는 이미지를 리사이징하여 jpeg형식으로 변환하고 보냈습니다. 아마존 S3서버가 jpeg 형식을 알아서 지원한다고 하여 문제가 없을 것이라 생각하였습니다. 그런데 S3서버에는 미리 정한 파일명에 4KB의 빈 내용이 들어가거나 이미지 파일만 사라진 채로 요청의 Payload가 문자열로 담긴 파일이 생성되었습니다. 처음엔 프론트에서 파일이 누락되었거나 이미지 리사이징 중 감지하지 못한 오류가 발생한 것이라고 생각하였습니다. 하지만 문제는 다른 곳에 있었습니다. 프론트에서 presinged URL로 파일을 보낼 때에만 헤더에 Content-type을 넣으면 될 줄 알았지만 백엔드 서버에서 Presinged URL을 발급 요청할 때부터 Content-type을 지정하여 주어야했습니다. 프론트에서 모든 이미지를 jpeg로 압축하기 때문에 Presinged URL에 jpeg 파일이 전송될 것이라고 지정하여 발급받으니 정상적으로 업로드 되었습니다.

 

참고로 파일이 업로드되면 S3 버킷 주소 + 파일 명이 해당 객체의 주소가 됩니다. 그리고 S3에 업로드 되는 이미지 파일은 base64, binary 등의 인코딩된 데이터를 올려도 알아서 디코딩하기 때문에 해당 주소에서 즉시 이미지로 불러올 수 있습니다.

 

4. 이미지를 업로드하자마자 조회하면 이미지가 안불러져요. 이미지 조회 403 Forbidden

S3 서버에서 조회 권한은 Public으로 설정했습니다. 이미지를 조회할 때 img 태그에 src에 S3 링크를 넣어서 사용하기 때문이었습니다. 그런데 이미지를 업로드 한 뒤, img태그의 src 속성이 올바르게 적용되었음에도 불구하고 이미지가 바로 불러와지지 않았습니다. 해당 링크로 직접 접속하면 이미지가 정상적으로 보였기 처음엔 제 코드의 캐싱 관련 문제인 줄 알고 한참동안 씨름하였으나, 문제는 다른 곳에 있었습니다. 개발자 도구의 네트워크탭을 확인하여 보니 해당 이미지 소스에 대한 요청이 403 Forbidden이었습니다. 분명 접근권한이 퍼블릭이었음에도 불구하고 말이죠.

 

만약 404 에러코드였다면, 업로드가 완료되지 않고 조회를 한 것이 문제였겠지만 에러 코드가 403이라는 점과 업로드 완료 응답을 받은 뒤 조회하였기 때문에 해당 문제는 아니었습니다. 그리고 S3 버킷의 권한 설정이 문제였다면 이후 새로 고침에서도 동일한 403에러가 발생하여야 했기에 권한 설정 관련 문제도 아니었습니다.

 

많은 고민 끝에 제가 해결한 방법은 사진을 업로드 한 뒤 setTimeout을 통해 50ms가 지난 후 이미지를 조회하도록 한 것이었습니다.  이미지 업로드 후 새로 고침을 하거나 추가로 이미지 업로드, 혹은 직접 링크에 접속하였을 때 이미지가 정상적으로 조회되는 것을 보았을 때, 이미지 업로드 후, 권한이 퍼블릭으로 업데이트 되는 시간이 필요하지 않을까라는 생각이었습니다. 다행히 이 방법으로 이미지가 정상적으로 처리되었습니다. 1ms도 시도해보았지만 역시 403 응답을 받았습니다. 원인을 정확하게 파악하지는 못했지만 업로드 완료 이후, 조회까지 여유 시간이 필요하다는 점만은 확실해보였습니다.

+ Recent posts