業務向けのサービスで、任意の時間内に限定してアクセス可能なサインアップページを用意する必要がありました。

こういったケースでは、S3の期限付きURL(pre-signed urlと呼ばれる)を発行させるのが便利そうです。ということで早速nodeで試してみました。

node.jsから期限付きURLを得る

まずはaws-sdkをインストールします。

bash
1
npm install aws-sdk --save

次にnodeから実行するjsファイルへ、S3バケットやアクセス許可する時間を記述していきます。

index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var AWS = require('aws-sdk');
AWS.config.update({
"accessKeyId": "< IAMユーザーアクセスキー ID >",
"secretAccessKey":"< IAMユーザーシークレットアクセスキー >",
"region": "< リージョン >" });

var s3 = new AWS.S3();
var params = {
Bucket: '< アクセスするS3バケット名 >',
Key: '< アクセスするhtmlファイル等 >',
Expires: < アクセスを許可する時間(秒) >
};
s3.getSignedUrl('getObject', params, function (err, url) {
console.log("The URL is", url);
});

例えば、S3にcognito-signupというバケットを用意し、./signup.htmlへ1時間に限りアクセス許可させたい場合には以下のようになります。

index.js
1
2
3
4
5
6
var s3 = new AWS.S3();
var params = {
Bucket: 'cognito-signup',
Key: 'signup.html',
Expires: 60*60
};

実行すると期限付きURLが発行されます。

bash
1
2
$ node index.js
The URL is https://cognito-signup.s3-your-region.amazonaws.com/signup.html?AWSAccessKeyId=xxx&Expires=xxx&Signature=xxx

かなり手軽に生成できますね。LambdaやEC2から生成させるなど、限定してアクセスしてもらいたい場合に活用したいと思います。

参考記事

以下の記事が参考になりました。

S3の期限付きURLを生成する | Developers.io
https://dev.classmethod.jp/cloud/aws/node-pre-signed-url/

注意点としては、期限に設定できる期間は1秒から604800(7日間)だそうです。

S3の事前署名付き(期限付き)URLに設定できる期限には上限がある | Qiita
https://qiita.com/kikuchy/items/223ced22d824bec78e1a

また、GETだけでなく、S3のオブジェクトをPUTすることもできるようです。以下の例では期限付きURLを発行した後でcurlからファイルをアップロードしています。

Boto3でS3のpre-signed URLを生成する | Developers.io
https://dev.classmethod.jp/cloud/aws/generate-pre-signed-url-for-s3-with-boto3/
S3 オブジェクトを更新するときにも pre-signed URL は使えます。 この機能を利用すると、モバイル端末や外部サービスなどから一時的に権限を付与し、S3 に直接アップロードさせることもできるようになります。