Boto3でS3のpre-signed URLを生成する
AWS は認証付き URL を生成することで AWS のリソースを第三者が操作できるようにする仕組みがあります。
今回は、この機能を活用し
- S3 にオブジェクトを PUT
- S3 のオブジェクトを GET
の2パターンに対して Python SDK boto3 を使って認証付きのURL(pre-signed URL)を生成したいと思います。
Boto3 の低レイヤーの botocore に generate_presigned_url
というメソッドがあるので、このメソッドを活用します。
S3 にオブジェクトを PUT
import boto3 BUCKET = 'YOUR_BUCKET' KEY = 'YOUR_KEY' s3 = boto3.client('s3') print s3.generate_presigned_url( ClientMethod = 'put_object', Params = {'Bucket' : BUCKET, 'Key' : KEY}, ExpiresIn = 3600, HttpMethod = 'PUT')
引数 | 意味 |
ClientMethod | S3へのリクエストで利用するAPIです |
Params | ClientMethodで利用する引数です |
ExpiresIn | URLの有効期間を秒で指定します |
HttpMethod | S3へのリクエストで利用するHTTPメソッドです |
実際に実行すると以下のような URL が生成されます。
https://YOUR_BUCKET.s3.amazonaws.com/YOUR_KEY
では、この URL を使って S3 にオブジェクトを登録してみましょう。
$ export URL=https://YOUR_BUCKET.s3.amazonaws.com/YOUR_KEY # generated pre-signed URL $ echo abcde > test.txt $ curl -D - -X PUT --upload-file test.txt $URL HTTP/1.1 100 Continue HTTP/1.1 200 OK x-amz-id-2: 9J3B1F6kcpjEszB8w0RJCyOlJPdjWyNDHxRhiQ0bl9NmZGD64iysF/e9Wr9vDWxj4MN1KyOoIlo= x-amz-request-id: 251BCE507696A64B Date: Sat, 26 Dec 2015 07:36:39 GMT ETag: "9b9af6945c95f1aa302a61acf75c9bd6" Content-Length: 0 Server: AmazonS3
登録したオブジェクトを確認して見ます。
$ aws s3 cp s3://YOUR_BUCKET/YOUR_KEY - abcde
アップロードしたものと同じですね。
S3 のオブジェクトを GET
今度は pre-signed URL を使って S3 オブジェクトを GET します。
素の GET リクエストでは 403 Forbidden エラーが発生します。
$ curl http://YOUR_BUCKET.s3.amazonaws.com/YOUR_KEY <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>D191003BF8C99932</RequestId><HostId>/4KatDswKFl3MTgyCUNY8MIqwYR1eI2DuKjqVfw/LtJSnnEhtP5KJ5TgnHF9XPpZRZ4xoE1r+0I=</HostId></Error>
先ほどと同じく generate_presigned_url
で pre-signed URL を生成します。
S3 get_object
API を使うように書き換えています。
import boto3 BUCKET = 'YOUR_BUCKET' KEY = 'YOUR_KEY' s3 = boto3.client('s3') print s3.generate_presigned_url( ClientMethod = 'get_object', Params = {'Bucket' : BUCKET, 'Key' : KEY}, ExpiresIn = 3600, HttpMethod = 'GET')
生成された URL を使って実際にアクセスしてみましょう。
$ URL="https://YOUR_BUCKET.s3.amazonaws.com/YOUR_KEY $ curl -D - -X GET $URL HTTP/1.1 200 OK x-amz-id-2: 4O+FU7EUoRXkEBIT1tlimhVqUGgUZ1GhydBDZvKhQOcuLXywWaK2l5T3vHmFDPG36L34P63xnYs= x-amz-request-id: 694599C7F47D22AC Date: Sat, 26 Dec 2015 08:01:57 GMT Last-Modified: Sat, 26 Dec 2015 07:56:33 GMT ETag: "9b9af6945c95f1aa302a61acf75c9bd6" Accept-Ranges: bytes Content-Type: binary/octet-stream Content-Length: 6 Server: AmazonS3 abcde
アップロードしたものと同じオブジェクトを取得出来ています。
まとめ
S3 オブジェクトを取得する pre-signed URL はよく使われますが、S3 オブジェクトを更新するときにも pre-signed URL は使えます。 この機能を利用すると、モバイル端末や外部サービスなどから一時的に権限を付与し、S3 に直接アップロードさせることもできるようになります。