見出し画像

CroudFrontのCORS沼から脱出する方法

APIなどで別ドメインへのアクセスを使用する静的サイトをCroudFront経由で公開する過程でCORSでハマったので覚書。

AWS利用のサービス

  • Route53

  • S3

  • CloudFront

なんか、こんな感じで、本来はサクっと行けるのですが…

ダメだった現象

静的サイトとして公開はできたものの、APIを叩くとCORSエラーで終了します。ブラウザがこのアドレスでAPIはダメよ?と仁王立ち。

S3のCORS設定やCloudfrontのヘッダポリシーを設定しても、どーしてもヘッダに CORSに必要な  Access-Allow-Origin とか、ぜーんぜん1つも追加してくれません。

借り物の画像です。世の中で一番イライラするのはこのエラー。
ネイティブプログラマーを殺すにはCORSが一番

日本語英語で関連情報を調べまくって様々な組み合わせを試すもダメ。1つ見えてきたのは、多くの人が苦しんでいる、 CloudFrontのキャッシュが場合によりCORSを返さない(返したり返さなかったりする)という現象。 どうやらこの罠にわたしもかかってしまったようです🐇


解決した設定を公開

まずは結論から!

1️⃣ S3 CORSの設定

S3>バケット のページから アクセス許可のタブをえらび、

Cross-Origin Resource Sharing (CORS) の編集をします

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "Etag"
        ]
    }
]

2️⃣  CroundFront の設定

公開して表示を確認したら以下のようにキャッシュポリシーを設定。

画像最後の設定は、以下の関数(functions)を追加すると流れで行えます。
ダメなら手動で〜

  Cloudfront functions  (これが決め手)

Cloudfront の関数 (functions ) に好きな名前で以下の関数を追加します。
追加したら Cloudfront のビヘイビアから関数を追加設定します。

async function handler(event) {
    const request = event.request;
    const headers = request.headers;
    const host = request.headers.host.value;
   
   // If origin header is missing, set it equal to the host header.
   if (!headers.origin)
       headers.origin = {value:`https://${host}`};
       
   return request;
}

以上!!

こんな状態らしいです


🔥実行確認

curl で確認

$curl -i "https://my-site.com
HTTP/2 200 
content-type: text/html
content-length: 511
date: Wed, 02 Oct 2024 11:29:34 GMT
access-control-allow-origin: *
access-control-allow-methods: GET, HEAD, PUT, POST, DELETE
access-control-expose-headers: Etag

あるある! access-control-allow-methods 関連がS3のCORSの設定の通りです


ブラウザで確認

ページを開いて inspector のネットワークで確認します。

あるあるある!

以上!!

※もっとスマートな方法があったら是非お知らせください。めっちゃ感謝します!


実は金曜日にサクッと終わるはずが土日月を使ってそれでもダメで4日近く悩みましたょ。。。おかげでAWSのコンソールといまだかつて無いくらい仲良しにはなりましたが(笑



なんか、紆余曲折あったっぽい

ものすごくハマッた理由として、ネット上に時期によってまちまちのことが書かれていまして、どうやらCloudfront・S3のこのあたりの仕様が内部的に変わった雰囲気があるのと、CORSどーすんじゃい!という苦情が相当あったのでしょう、何度か追加機能としても発表がされています(しかも最近)

はっきりしているのは以下の2つですがブログなどを片っ端から見て実験した感じでは、明らかにCORS関連のキャッシュのアルゴリズムが何度も変わっている(もしくはバグっってる、その両方)な印象。。。

1.これでできるよー!ってうガセネタ。(本家)


2.ヲイヲイっ!じゃあ今までのは何だったんだ?っていう正解(本家)


商売なのでアレでしょうけど。。。

まあ、ようするにCloudFront使うならAPIとか他のこともまるっとAWSをつかってすべて課金させろや?っていうことみたいです。(笑
ちなみに解決策のfunctionsも追加で課金されますので、S3で安く静的サイト公開した上にAPIとかてんこ盛りの「SaaSを公開して一儲けするとかしないよなぁ?」っという意思表示なのかもしれません。

ええ、そんなこたあぁしませんとも。(汗



サポートありがとうございます😊 ベトナムにお越しの際はお声がけくださいね🌻