S3の署名付きURLでアップロードしたオブジェクトにメタデータをセットする方法

2020.02.29

大阪オフィスの小倉です。

S3の署名付きURLを使ってオブジェクトをアップロードする際、メタデータをセットする方法を紹介します。

署名付きURLでアップロードしたオブジェクトにメタデータをセットする

boto3を使って以下の要領で署名付きURLを作成しておくと、
署名付きURLを介してオブジェクトがアップロードされた際に、自動でメタデータを付加することが出来ます。

import boto3
from botocore.config import Config

BUCKET = 'upload-test'
KEY = 'testkey'

s3 = boto3.client('s3', config=Config(signature_version='s3v4'))

url = s3.generate_presigned_url(
    ClientMethod='put_object',
    Params={
        'Bucket': BUCKET,
        'Key': KEY,
        'Metadata': {'author': 'ogura'}},
    ExpiresIn=3600,
    HttpMethod='PUT'
)
print(url)

Metadataという項目に、付加したいメタデータのキーと値を設定しておきます。

発行したURLを使って、curlコマンド等でリクエストを送りアップロードします。

curl -X PUT -H 'x-amz-meta-author:ogura' --upload-file test.txt (作成した署名付きURL)  

アップロードされたオブジェクトを確認すると、x-amz-meta-(ユーザが定義したキー)の名前でメタデータが付加されています。

例えばアプリケーションから複数の相手に署名付きURLを発行し、オブジェクトをアップロードしてもらうような場合に、
メタデータに相手の名前を含めた署名付きURLにしておけば、バケット内のオブジェクトメタデータから、誰がアップロードしたかが判別できるでしょう。

アップロード時の注意点(ハマったこと)

結論から言うと、署名付きURL作成時の署名バージョンの違いで、
アップロードする際に必要なリクエストパラメータが異なっていました。

サンプルコードは、config=Config(signature_version='s3v4')の記載があるため、
署名バージョン4で動作しています。

一方、config=Config(signature_version='s3v4')を付けず、
署名バージョン2で署名付きURLを作成すると、以下のコマンドでもアップロードが可能です。

curl -X PUT --upload-file ./test.txt (作成した署名付きURL)

署名バージョン4で作成したURLの場合、-Hオプションを使用して
追加したメタデータのキーと値をリクエストヘッダに含めておく必要がありました。
一方、署名バージョン2の場合、ヘッダの指定は不要です。(ヘッダを指定してもアップロード可能です)

私の場合は冒頭のコードにconfig=Config(signature_version='s3v4')の指定をするのを忘れていて、
アップロード時のパラメータの違いに??? となっていました。

小ネタでしたが、どなたかのお役に立てば幸いです。

以上、大阪オフィスの小倉でした。

参考資料

S3におけるAWS署名バージョン2の廃止