概要
CloudFrontFunctionsを利用して、クライアントからのリクエストに対してBasic認証やAPIKey認証(リクエストヘッダーを参照して突き合わせ)を実装する機会があったので、備忘録としてコードを残しておきます。
・CloudFrontFunctionsとは
CloudFrontディストリビューションへのアクセス時に、軽量のJavaScriptコードを実行する事が可能な仕組みです。
<公式の説明>
関数を使用してエッジでカスタマイズする - Amazon CloudFront
エッジ関数を使用して、Amazon CloudFront ディストリビューションをカスタマイズします。
構築手順
↓公式のリファレンスにそこそこ分かり易く記載されています。
※ザックリ書くとこんな感じです。(簡単!)
1.CloudFrontのページから「関数」選択
2.関数名を入力して、JavaScriptを記述→「変更を保存」
3.任意のディストリビューションに関連付け→「関数を発行」
(初回だけ「関数を発行」してからディストリビューションに関連付け→「関数を発行」)
<公式のリファレンス>
チュートリアル: CloudFront Functions でシンプルな関数を作成する - Amazon CloudFront
このチュートリアルを完了すると、簡単な関数を作成して CloudFront Functions を使用できるようになります。
Basic認証
コード
var authUser = 'user'; // ユーザ名をべた書き
var authPass = 'pass'; // パスワードをべた書き
function handler(event) {
// Basic Authenticate
var request = event.request;
var headers = request.headers;
var authString = 'Basic ' + (authUser + ':' + authPass).toString('base64');
if (
typeof headers.authorization === "undefined" ||
headers.authorization.value !== authString
) {
return {
statusCode: 401,
statusDescription: "Unauthorized",
headers: { "www-authenticate": { value: 'Basic realm="Message"' } }
};
}
return request;
}
疎通確認
・curlからアクセス(以下はPOSTするケース)
$ curl -X POST --user user:pass https://<cloudfrontディストリビューションドメイン名>/xxx/yyy
・ブラウザからアクセス その1
↓のように下記URLへブラウザからアクセス
https://<cloudfrontディストリビューションドメイン名>/xxx/yyy
※コードにべた書きした「ユーザ名」と「パスワード」を入力して、「ログイン」を押下する事でアクセス可能
・ブラウザからアクセス その2
※URLに直接Basic認証情報を記述しておく方法
https://user:pass@<cloudfrontディストリビューションドメイン名>/xxx/yyy
APIキー認証(リクエストヘッダー参照)
コード
・リクエストヘッダー内の’xxx-api-key’に含まれる値で認証
var authApiKey = 'apikey'; // APIKeyをべた書き
function handler(event) {
// ApiKey Authenticate
var request = event.request;
var headers = request.headers;
if (
headers['xxx-api-key'].value !== authApiKey
) {
return {
statusCode: 401,
statusDescription: "Unauthorized",
};
}
return request;
}
疎通確認
・curlからアクセス(以下はPOSTするケース)
$ curl -X POST -H "xxx-api-key:apikey" https://<cloudfrontディストリビューションドメイン名>/xxx/yyy
※その他Postmanなどのリクエストツールをご利用ください。
おまけ:リクエストパスで認証方法を分岐
コード
var authApiKey = 'aaa';
var authBasicUser = 'bbb';
var authBasicPass = 'ccc';
function handler(event) {
// Basic & APIKey Authenticate
var request = event.request;
var headers = request.headers;
var uriTop = request.uri.split('/').slice(1,2).join(''); // ディストリビューションドメイン名以降のパスを'/'で分割した際の1つ目(/pass1/pass2/pass3ならpass1)
var uriApi = request.uri.split('/').slice(3,4).join(''); // ディストリビューションドメイン名以降のパスを'/'で分割した際の3つ目(/pass1/pass2/pass3ならpass3)
// 以下の分岐ではリクエストパスが[/pass1/*/pass3] or [/pass1/*/passX]の場合認証処理を実行
// APIKey Auth
if (uriTop === 'pass1' && uriApi === 'pass3') {
if (headers['xxx-api-key'].value !== authApiKey ){
return {
statusCode: 401,
statusDescription: "Unauthorized"
};
}
}
// Base Auth
else if (uriTop === 'pass1' && uriApi === 'passX') {
var authString = 'Basic ' + (authBasicUser + ':' + authBasicPass).toString('base64');
if (typeof headers.authorization === "undefined" || headers.authorization.value !== authString) {
return {
statusCode: 401,
statusDescription: "Unauthorized",
headers: { "www-authenticate": { value: 'Basic realm="Message"' } }
};
}
}
else {
return {
statusCode: 401,
statusDescription: "Unauthorized"
};
}
return request;
}
コメント