【Javascript】CloudFront 署名付きURLを生成
Javascriptを使った、CloudFront署名付きURLの生成方法です。
前提
本件は、S3の前にCloudFrontを配置し、署名付きURLを介してS3オブジェクトをブラウザで表示してみるという構成を想定してコードを書きました。
また、CloudFrontディストリビューションがデプロイ済みであり、キーペア作成済み、パブリックキーがCloudFront側にアップロード済みであることが前提です。
以下の記事で触れてますのでよければどうぞ。
【Python】CloudFront 署名付きURLを生成Javascript サンプルコード
共通部分
const fs = require('fs');
const cloudfrontDistributionDomain = "https://xxxxxx.cloudfront.net";
const s3ObjectKey = "icon.png";
const keyPairId = "パブリックキーID"; // キーグループのIDではない
var sigened_url;
/**
* プライベートキーを読み出す
*
* `options={encoding: "utf8"}` とすると、プレーンテキストで読み出せる
*/
function _read_private_key_contents(options = {}) {
return fs.readFileSync("cloudfront_private_key.pem", options);
}
/**
* 有効期限を生成する
*
* @param {number?} n 有効期間(単位 分)
* @param {string?} format returnする型. stringの場合 `YYYY-MM-DD HH:ii:ss`、それ以外は timestamp(ms)
*/
function _get_after_n_minutes_datestring(n = 10, format = "string") {
const afterNmin = (n * 60 + 1) * 1000; // 1秒未満切り上げのため +1 sec 、単位ms
let dt = new Date();
dt.setMilliseconds(dt.getMilliseconds() + afterNmin);
if (format !== "string") {
return dt.getMilliseconds();
}
// "YYYY-MM-DD HH:ii:ss" で出力する
const year = String(dt.getFullYear());
const month = String(dt.getMonth() + 1).padStart(2, '0');
const date = String(dt.getDate()).padStart(2, '0');
const hour = String(dt.getHours()).padStart(2, '0');
const min = String(dt.getMinutes()).padStart(2, '0');
return `${year}-${month}-${date} ${hour}:${min}:00`;
}
AWS SDK v3 の場合
追加のライブラリをインストールします。
npm install @aws-sdk/cloudfront-signer
サンプルコードです。
/** およそ10分間有効な署名付きURLを生成する v3 */
function generate_signed_url_v3(domain) {
const {getSignedUrl} = require("@aws-sdk/cloudfront-signer");
const url = `${domain}/${s3ObjectKey}`;
const privateKey = _read_private_key_contents();
const expire = _get_after_n_minutes_datestring();
return getSignedUrl({
url,
keyPairId,
dateLessThan: expire,
privateKey,
});
}
function sdkV3() {
sigened_url = generate_signed_url_v3(cloudfrontDistributionDomain);
console.log(sigened_url);
// 代替ドメインを使用する場合
const d2 = 'ここに代替ドメイン';
sigened_url = generate_signed_url_v3(d2);
console.log(sigened_url);
}
sdkV3();
AWS SDK v2 の場合
追加のライブラリをインストールします。
npm install aws-cloudfront-sign
サンプルコードです。
/** およそ10分間有効な署名付きURLを生成する v2 */
function generate_signed_url_v2(domain) {
const cfsign = require('aws-cloudfront-sign');
const url = `${domain}/${s3ObjectKey}`;
const privateKey = _read_private_key_contents();
const expire_ms = _get_after_n_minutes_datestring(format = "int") / 1000;
const signingParams = {
keypairId: keyPairId,
privateKeyString: _read_private_key_contents(options = {encoding: "utf8"}),
expireTime: expire_ms,
};
return cfsign.getSignedUrl(url, {
keypairId: keyPairId,
privateKeyString: _read_private_key_contents(options = {encoding: "utf8"}),
expireTime: expire_ms,
});
}
function awsCloudfrontSign() {
sigened_url = generate_signed_url_v2(cloudfrontDistributionDomain);
console.log(sigened_url);
// 代替ドメインを使用する場合
const d2 = 'https://代替ドメイン';
sigened_url = generate_signed_url_v2(d2);
console.log(sigened_url);
}
console.log("[S3/CloudFront] 署名付きURLを発行 V2");
awsCloudfrontSign();
参考ページ
v2で参考になった記事
Creating Amazon CloudFront Signed URLs in Node.js Class: AWS.CloudFront.Signerv3で参考になった記事
AWS SDK for JavaScript v3 - @aws-sdk/cloudfront-signer Github - aws-sdk-js-v3