로컬에서 다운로드 버튼을 클릭했을 때 AWS S3 버킷에 있는 파일이 유저의 기기에 저장이 됐다. 열어서 멀쩡한 것까지 확 다 했는데. 서버 배포하니까 xml이 다운받아지더라.
네트워크 창에도 400 Bad Request가 떴고 다운로드 된 xml을 보니, 다음과 같은 에러 메시지가 나왔다.
<Error>
<Code>InvalidRequest</Code>
<Message>The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.</Message>
<RequestId>TW6Y0BB3D51GD68M</RequestId>
<HostId>8wFBGILAxoWxYVrO4Hz66PLC/mydzVh4t1o+Dp//K29GVT0r+PVtAubJ6FUea2rreNGppw+hazI=</HostId>
</Error>
찾아보니 이 오류는 일반적으로 AWS S3와 통신할 때 자주 발생한다고 한다.
내가 버킷 객체를 요청하는 과정에서 사용된 인증 메커니즘이 AWS에서 요구하는 인증 메커니즘과 일치하지 않음을 나타내는데 presigned url이라는 방식으로 객체 url을 생성하는 방법에서 발생하는 오류이다.
AWS는 api 요청을 승인하기 위해서 다양한 signature 알고리즘을 사용하는데 내가 만난 에러메시지는 내 요청이 과거의 인증 메커니즘을 사용한다는 것이었다. AWS 문서에는 최신 리전이나 서비스에서 더이상 지원하지 않는 버전(v2)을 내가 사용했다고 한다.
v4라고 하는 AWS4-HMAC-SHA256
이 signature 버전은 당연하게도 이전과는 다른 강화된 보안 방식을 제공한다고 한다. 그래서 url이 있는 유저만 접근할 수 있는 presigned-url을 생성할때는 이 인증 방식을 사용해야 했다.
사실 지금 테스트중인 s3버킷은 퍼블릭 객체이긴 하지만 presigned url 테스트 겸 presigned-url 생성 코드를 사용하고 있는데 그래서 해당 에러가 날 수 밖에 없었다.
from botocore.config import Config
my_config = Config(
signature_version = 'v4',
)
s3_client = boto3.client('s3',
config=my_config,
region_name='ap-northeast-2',
aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY")
)
이런 식으로 설정하면 된다.