CloudFront で DirectoryIndex (署名付き URL / Cookie 設定時)

概要

S3 オリジン + 署名付き URL / Cookie を設定する場合、S3 の Static website hosting は使えない。

なので、http://bucketname.s3-website-ap-northeast-1.amazonaws.com のような Static website hosting 用のエンドポイントではなくhttps://s3-ap-northeast-1.amazonaws.com/bucketname のような REST API エンドポイントを CloudFront のオリジン設定として指定することになる。

その結果、Apache httpd で言うところの DirectoryIndex が効かないことになる。

例: https://example.com/dir/ アクセス時。

  • 想定される動作: => /dir/index.html のコンテンツが表示されること
  • 実際の動作: エラー

Static website hosting 用のエンドポイントが使えればこのような問題は発生しない。

Lambda@Edge を使った対策

対策として、CloudFront のオリジンリクエストイベントを使用して、Lambda@Edge でオリジンへのリクエストを改ざんしてしまえば良い。

'use strict';

module.exports.lambda_handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const viewer_uri = request.uri;

  // Complement directory index file name
  const origin_uri = viewer_uri.replace(/\/$/, '\/index.html');

  console.log(`Viewer URI: ${viewer_uri}`);
  console.log(`Origin URI: ${origin_uri}`);

  request.uri = origin_uri;

  callback(null, request);
};

この Lambda 関数を CloudFront のビヘイビア設定にて Origin Request をトリガーに指定。

serverless.yml はこちら。

😇

参考

できた!S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法 | Developers.IO