【S3・CloudFront】URL の末尾が/(スラッシュ)で終わるリクエストを/index.html にルーティングする
はじめに
S3とCloudFrontで静的サイトをホスティングする際、設定によっては、URL の末尾が/(スラッシュ)で終わるリンクをクリックするとき、正しくルーティングできないことがあります。
(例:hrefが/case/のリンクをクリック → 内部的には/case/index.htmlにリンクさせたいがエラーになる)
この解決法としては、2点あります。
①S3のREST APIエンドポイント + CloudFront Functionsを使用する方法
- OAC (Origin Access Control) を利用
- CloudFront Functionsを利用
②S3のウェブサイトエンドポイント + カスタムヘッダーを使用する方法
- カスタムヘッダーを使用してバケットポリシー+CloudFrontでアクセス元を制限
※S3のREST APIエンドポイントとウェブサイトエンドポイントについて
①S3のREST APIエンドポイント + CloudFront Functionsを使用する方法
S3の実装
S3のブロックパブリックアクセスをオン
にしておきます。
バケットポリシー
{
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケットネーム/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "CloudFrontのディストリビューションARN"
}
}
}
]
}
CloudFrontの実装
CloudFrontのオリジン設定をREST APIエンドポイントのURLに設定します。
**※URLにwebsite
が付かないように
次にCloudFrontでオリジンアクセスを作成し、オリジンにアタッチしてOACを設定します。
ここまでで、静的サイトのホスティング自体はできています。
ここからはCloudFront FunctionsでURLを整形する関数を作成していきます。
CloudFrontの左ペインの関数
で作成します。
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith("/")) {
request.uri += "index.html";
}
// Check whether the URI is missing a file extension.
else if (!uri.includes(".")) {
request.uri += "/index.html";
}
return request;
}
作成したら該当のディストリビューションのビヘイビア
の関数の関連付け
で作成した関数をアタッチします。 今回はエンドユーザーからのリクエストをCloudFrontが受け取った直後に発火させたいので「ビューワーリクエスト」で選択します。
こちらで①の設定は完了です。
ビューワーリクエスト等についての参考
②S3のウェブサイトエンドポイント + カスタムヘッダーを使用する方法
S3の実装
S3のブロックパブリックアクセスをオン
にしておきます。
(バケットポリシーでS3のエンドポイントに直接アクセスできないようにします)
バケットポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontAccess",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケットネーム/*",
"Condition": {
"StringEquals": {
"aws:Referer": "CloudFrontのRefererヘッダーの値"
}
}
}
]
}
S3の静的ウェブサイトホスティングをオン
にします。
また、インデックスドキュメントの値にindex.html
を設定しておきます。
CloudFrontの実装
CloudFrontのオリジン設定をウェブサイトエンドポイントのURLに設定します。
カスタムヘッダーを設定します。値は任意でOKです。(バケットポリシーにも記載)
こちらで②は完了です。
おわりに
今回は、S3とCloudFrontにおける末尾スラッシュ問題を解決するための2つの実践的な方法、①REST APIエンドポイント + CloudFront Functions と ②ウェブサイトエンドポイント + カスタムヘッダー をご紹介しました。
方法①はOACを利用するためセキュリティ面で優れており、AWSが推奨するモダンな構成です。CloudFront Functionsによる柔軟な制御も魅力です。
方法②はS3の標準機能で解決でき、設定がシンプルというメリットがあります。
基本的にはセキュリティと拡張性の高い①の方法をおすすめしますが、要件や手軽さに応じて②を選択するのも良いと思います。
Discussion