はじめに
Amazon Simple Storage Service (Amazon S3) は、高いスケーラビリティ・可用性・パフォーマンスなどを提供するオブジェクトストレージサービスです。Web サービスで画像データをアップロードしたいときに、S3 の署名付きURL を活用することが出来ます。
画像データをアップロードする際に、アプリケーションサーバーなどのバックエンドサーバーを経由する方法がありますが、CPU やネットワーク、メモリなどのリソース消費が気になります。アップロードの頻度が多く容量が大きいファイルだと、パフォーマンスへの影響が無視できません。そこで、ブラウザから直接 S3 にアップロードする方法を採用できます。
一方、セキュリティの観点で、S3 Bucket は Private にしておきたいです。Private のまま一時的にアップロードのための URL を生成する機能が、S3 署名付きURL です。
今回の記事では、ファイルをアップロードするための、S3 署名付きURL を確かめる記事になります。
S3 Bucket を作成
まず、署名付きURL を使ってアップロードするための S3 Bucket を作成します。Create Bucket を押します
適当に Bucket 名を付けます
それ以外はデフォルトのまま作成をします。S3 Bucket は Private Bucket で作成しています。
Create を押します
S3 Bucket が作成されました
Pythonで署名付きURLを生成
次に、ファイルをアップロードするための、署名つきURLを生成します。AWS SDK を使って生成していきます。(AWS CLI では、アップロード用の署名付きURLは生成できません)
Python プログラムを作成するための、作業用ディレクトリを作ります。
mkdir ~/python/s3-create-presign-upload
Python ファイルを作成します
touch ~/python/s3-create-presign-upload/s3-create-presign-upload.py
動作確認用ソースコードです。エラーハンドリングはしていないので、本番環境では気を付けましょう。
- Params に、アップロード先のバケット名と、オブジェクト名を入れて、署名付きURL を生成している
- Bucket を作成した直後だと、次の URL にあるとおりエラーになる可能性がある。そのため、署名付きURL の
s3.amazonaws.com
をs3.ap-northeast-1.amazonaws.com
に置換している
import boto3
s3_client = boto3.client('s3', region_name='ap-northeast-1')
url = s3_client.generate_presigned_url(
ClientMethod='put_object',
Params={'Bucket': 's3-presigned-test01', 'Key': 'this-is-filename.txt'},
ExpiresIn=3600)
url = url.replace('s3.amazonaws.com', 's3.ap-northeast-1.amazonaws.com')
print(url)
Python プログラムの実行例です。S3 の URL に、Accesskey や署名や、有効期限がパラメータとして付与されています。
> python s3-create-presign-upload.py
https://s3-presigned-test01.s3.ap-northeast-1.amazonaws.com/this-is-filename.txt?AWSAccessKeyId=xxxxxxxxxxxxx&Signature=yyyyyyyyyyy&Expires=1645609221
curl でテキストファイルをアップロード
それでは、curl コマンドで実際にアップロードをしていきましょう。
適当なテキストファイルを生成します
echo "Hi! I am Test File with S3 Presigned URL!" > test.txt
curl でアップロードします
url=$(python s3-create-presign-upload.py)
curl -X PUT \
--upload-file test.txt \
$url
S3 Bucket にアップロードされています。Download をして、中身を確認してみましょう
正常にアップロードされています!
検証を通じてわかったこと
- 生成方法の違いについて
- S3 事前署名付き URL は、オブジェクトのダウンロード用とアップロード用の2種類がある
- ダウンロード用は、マネージメントコンソール・AWS CLI・AWS SDK から生成が可能
- 一方、アップロード用は、AWS SDK のみ生成が可能
- https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/PresignedUrlUploadObject.html
- アップロード用署名付き URL は、アップロード先のオブジェクト名を指定可能
- アップロード元のファイル名は、アップロード先のオブジェクト名にならない
- オブジェクト名は、署名付きURLを生成する側でコントロール出来るため、便利に活用できる
参考URL