エラーの内容
Cloudfrontとs3を使用してVue製のSPAフロントエンドをホスティングしている時に、「https://example.com/login」のような、root直下以外のurlパスを指定したり、リロードするとCloudfrontのAccessDenyのエラーが表示されてしまった。
原因
Cloudfrontのエラーページの設定をしていなかったため。
「/login」のようにroot直下の「/」以外に直接アクセスされたり、リロードされるとCloudfrontはオリジンの対応するhtmlを探しに行ってしまう。
当然、「login.html」のようなページは用意しないのでファイルが存在せず、エラーとなる。
解決策
CloudFrontのカスタムエラーレスポンスで、403のときに/index.html(今回は「/」)へ転送するよう設定する。
今回、フロントエンドのインフラをTypeScript版aws cdkで構築しているため、以下のように記述しデプロイした。
// CloudFrontディストリビューションを作成する
const distribution = new aws_cloudfront.Distribution(this, "Distribution", {
domainNames: ["example.com"],
certificate,
comment: "example.com",
defaultRootObject: "index.html",
defaultBehavior: {
allowedMethods: aws_cloudfront.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
cachedMethods: aws_cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS,
cachePolicy: aws_cloudfront.CachePolicy.CACHING_OPTIMIZED,
viewerProtocolPolicy:
aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
origin: new aws_cloudfront_origins.S3Origin(websiteBucket, {
originAccessIdentity,
}),
},
// 403エラーの時に「/」に飛ばす(SPAのため、リロードや直アクセスに対策するため)
errorResponses: [
{
httpStatus: 403,
responseHttpStatus: 200,
responsePagePath: "/",
},
],
priceClass: aws_cloudfront.PriceClass.PRICE_CLASS_100,
});
結果
Access Deniedのエラーが表示されることはなくなり、リロードされたり、URLで直接アクセスされても表示できるように修正できました。
参考文献
https://dev.classmethod.jp/articles/s3-cloudfront-spa-angular-403-access-denied/