👋

CloudFront + S3 構成のCORS設定について

2024/12/16に公開

まえがき

この記事は VR法人HIKKY Advent Calendar 2024 の 16 日目の記事です。
https://qiita.com/advent-calendar/2024/hikky

15日目は 自社製Webブラウザ用VRエンジンで3Dモーションライブを作った話 、17日目は 脱ドキュメント コーディングルールをEslint / Stylelintに任せる です。

概要

CloudFrontから期待されるCORSのレスポンスを返却するには、CloudFrontのキャッシュポリシー、オリジンリクエストポリシー、レスポンスヘッダーポリシーを適切に理解していないといけないため、いくつかハマりポイントがあります。
この記事ではCloudFront+S3構成を想定して、適切にCORSのレスポンスを返却できるように解説を行います。

CloudFrontのポリシー

CloudFrontには、以下の図のように、クライアントやOriginへのリクエスト、レスポンスを調整するための設定項目があります。

①キャッシュポリシー

キャッシュポリシーは、エッジロケーションにコンテンツをキャッシュする際のルールを定義する仕組みです。これにより、特定のデータがキャッシュされる条件や期間を柔軟に制御できます。
主に以下の項目を設定できます。

  1. TTL
    キャッシュの有効期間を秒単位で指定します。これにより、キャッシュデータがどのくらいの間利用可能かを制御できます。
  2. キャッシュキー
    キャッシュを区別する要素で、リクエストのヘッダー、クエリ文字列、Cookieなどを指定できます。
  3. 圧縮サポート
    一定の条件下で配信するコンテンツを圧縮することでデータ転送量を削減し、ユーザー体験を向上させる機能です。

キャッシュキーに指定されたヘッダーは、Originへのリクエストの際に同時に送信されます。
キャッシュキーの設定がCORSの設定をする際に重要で、設定によると以下のようなハマりポイントが存在します。

キャッシュキーにOriginの設定を行うようにする

複数のドメインからアクセスされることを想定している場合、アクセス元のドメインに対して適切な access-control-allow-origin を返却するために、キャッシュキーにOriginを指定する必要があります。
キャッシュキーにOriginの指定がなかった場合、複数のドメインに対して最初にキャッシュされたレスポンスが返却されてしまうため、access-control-allow-origin が別のドメインの指定で返却されます。

キャッシュキーにHostを指定してはいけない

こちらはOriginがS3の場合のハマりポイントですが、S3はリクエストに付与されたHostヘッダーをそのまま受け取り、それを元にバケットを判定します。CloudFrontがHostヘッダーを変更してS3に転送すると、S3はバケット名として解釈できずにリクエストを拒否します。

②オリジンリクエストポリシー

オリジンリクエストポリシーは、CloudFrontがオリジン(例: S3バケットやカスタムオリジン)にリクエストを送信する際に、どのリクエストデータ(ヘッダー、クエリ文字列、Cookieなど)を転送するかを制御する仕組みです。
必要最小限のデータだけをオリジンに送ることでパフォーマンスとセキュリティを向上したり、キャッシュ効率を最大化するため、不要なデータの転送を抑制します。

OriginがS3の場合には以下のようなハマりポイントが存在します。

ヘッダーにHostヘッダを含めてはいけない

キャッシュポリシーでのハマりポイント同様、S3に対してHostヘッダーを送信するような設定を行ってしまうと、S3へのアクセスが拒否されてしまいます。
CloudFront+S3構成の場合は、AWSが用意してくれている CORS-S3Origin を利用するのが良いでしょう。

③レスポンスヘッダーポリシー

レスポンスヘッダーポリシーは、CloudFrontがクライアント(エンドユーザー)にレスポンスを返す際に付与するHTTPレスポンスヘッダーを制御する仕組みです。
必要なHTTPヘッダー(例: セキュリティヘッダー、キャッシュ制御ヘッダー)をレスポンスに追加したり、ヘッダーの削除をしたりすることが出来ます。

CORS関連のヘッダをポリシーの設定の値で上書きするわけではなく、ポリシーはあくまでも許可、拒否するための設定になります。
例えば、以下のAWS側で用意されている CORS-With-Preflight ポリシーでは、Access-Control-Allow-Origin* が指定されていますが、ヘッダーを上書きして * に変更するのではなく、Originからの返却されたヘッダーに対して、どのパターンの値を許可するかという設定になります。

ハマりポイントとして、レスポンスヘッダーポリシーは許可する値を指定するという設定のため、レスポンスヘッダーポリシーのみを指定してOriginのCORSの設定を行わなかったためうまく動かないという場合があります。

まとめ

CloudFrontのCORSの設定ミスは特定のユーザーは閲覧可能だが特定のユーザーは閲覧できない、といったような調査しにくいバグを引き起こしてしまうため、正しく理解して設定しましょう。

Discussion