4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CloudFront+S3でSPAのルーティングをする方法(2021)

Posted at

はじめに

基本的な構築方法は省略

ルーティング問題

URLを/foo /bar の用に Router系でパス指定した場合、ローカルやNginx等では動いてたのにCloudFrontだと、403エラーになるという問題が起きる。これを回避するために CloudFrontで403エラーが発生したら /index.html に転送するという方法がよく行われている(というか自分もVue Routerで下記などの事例を参考に適用していた)。

なんでも200 OK問題

  • ファビコンをちゃんと用意してないとブラウザーが/favicon.icoを引っ張ってくるが/index.htmlのHTMLが転送される。(まあ、アイコンとして表示されないけど気持ち悪い)
  • 脆弱性検知ツール等がデバッグ用とか管理用のファイルとかのよくあるパスでアクセスしてきて、それに対して200で応答を返すので、そのファイル消したほうが良いって警告される。(まあ、そういうもんだって話ですが、監査を受けると説明しなきゃいけない)
  • foo.png bar.js hage.css とかなんでも/index.htmlのHTMLなのはどうなのか…。

CloudFront Functions

AWS samplesにそれっぽいものがある / -> /index.html/foo/ -> /foo/index.html って書き換えなので、上記のような書き換えだとうまく行かない。

なので、上記をベースに拡張子なし=ルーティングされたもの、と言う判断で書き換えれば良い。

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // Check whether the URI is missing a file extension.
    if (!uri.includes('.')) {
        request.uri = "/index.html";
    }

    return request;
}

Terraform

resource "aws_cloudfront_function" "test" {
  name    = "test"
  runtime = "cloudfront-js-1.0"
  comment = "my function"
  publish = true
  code    = file("${path.module}/function.js")
}
resource "aws_cloudfront_distribution" "example" {
  # 省略
  default_cache_behavior {
    # 省略
    function_association {
      event_type   = "viewer-request"
      function_arn = aws_cloudfront_function.test.arn
    }
  }
  # 省略
}
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?