1 min read

Amazon CloudFront Functionsを利用したbasic authentication と single page applicationのルーティングの実装

Amazon CloudFront Functionsを利用したbasic authentication と single page applicationのルーティングの実装
Photo by Dynamic Wang / Unsplash

概要

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;
}
basic-authentication-and-routing.js

次のステップ