Amazon CloudFront Functionsを利用したbasic authentication と single page applicationのルーティングの実装
概要
production環境以外の環境では特定のロールにのみフロントエンドアプリケーションを公開したいという要望があるときがあります。またsingle page applicationのroutingをinfrastructureで実現したいという要望があるとします。
この記事ではamazon cloudfront functionsを利用したbasic authenticationとsingle page applicationのroutingについて紹介します。
💡
amazon cloudfront functionsとはJavaScriptを使用して、CloudFrontを通過するリクエストやレスポンスの操作、基本認証と承認の実行、HTTPレスポンスの生成を行えるサービスです。cloudfront functionsの機能の詳細については、「CloudFront Functionsを使用したエッジでのカスタマイズ」をご覧ください。
前提
- amazon web servicesのawsアカウント
インフラリソースの構成
public cloudはamazon web servicesを利用します。
- Amazon CloudFront Distribution : cdn、static fileをキャッシュし配信する
- Amazon CloudFront Functions : edgeでのカスタマイズ、basic authenticationとrouting実行を行う
- Amazon S3 : object strage、フロントエンドアプリケーションのstatic fileを持つ
Amazon CloudFront Functionsの関数コード
Amazon CloudFront Distributionのbehaviorとcloudfront functionsをアタッチします。event typeはviewer requestです。
var ENABLE_BASIC_AUTHENTICATION = true;
var AUTHENTICATION_HEADER_VALUE = "Basic YOUR_BASIC_AUTHENTICATION_TOKEN"
var INDEX_FILE_PATH = "/index.html";
var unauthorizedResponse = {
statusCode: 401,
statusDescription: "Unauthorized",
headers: { "www-authenticate": { value: "Basic" } }
}
function hasAuthorizationHeader(value) {
return typeof value !== "undefined";
}
function validateAuthorizationHeader(value) {
return value === AUTHENTICATION_HEADER_VALUE;
}
function isFilePath(path) {
return path.indexOf(".") !== -1;
}
function generateFetchIndexFileRequest(request) {
var fetchIndexFileRequest = JSON.parse(JSON.stringify(request));
fetchIndexFileRequest.uri = INDEX_FILE_PATH;
return fetchIndexFileRequest;
}
function handler(event) {
var request = event.request;
var headers = request.headers;
if (ENABLE_BASIC_AUTHENTICATION) {
if (hasAuthorizationHeader(headers.authorization) === false) {
return unauthorizedResponse;
}
if (validateAuthorizationHeader(headers.authorization.value) === false) {
return unauthorizedResponse;
}
}
if (isFilePath(request.uri) === false) {
return generateFetchIndexFileRequest(request);
}
return request;
}