ユーザ用ツール

サイト用ツール


aws:cloudfront:cors

CloudFrontでCORS設定

CORSとは

読み方: コルス or シーオーアールエス

CORSは、Cross-Origin Resource Sharing(オリジン間リソース共有)の略です。
ブラウザーで閲覧しているページと違うドメインからリソースの取得を許可する仕組みです。

これは、ブラウザーの仕様であり、サーバー間同士などは問題ないです。

https://example.com
    CloudFront  ------> オリジン(S3, Nginx, Apache)
                         例
                         https://www.anything.net/video/call/System.generateId.dwr


オリジンでCORS設定がない時のエラーメッセージ

エラー「No 'Access-Control-Allow-Origin' header is present on the requested resource」


CORS設定ができているかの確認方法

https://aws.amazon.com/jp/premiumsupport/knowledge-center/no-access-control-allow-origin-error/

curl コマンドを実行して、オリジンが「Access-Control-Allow-Origin」ヘッダーを返すかどうかを確認します。

curl -H "origin: example.com" -v "https://www.anything.net/video/call/System.generateId.dwr"

実際のオリジンは、www.anything.netだけど、
example.comをオリジンとして、www.anything.netにアクセスする。
Nginxでオリジン設定ができていれば、example.comをオリジンとして認めて、正しい応答を返します。

HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 01 May 2018 03:06:41 GMT
Content-Type: text/html
Content-Length: 3770
Last-Modified: Thu, 16 Mar 2017 01:50:52 GMT
Connection: keep-alive
ETag: "58c9ef7c-eba"
Access-Control-Allow-Origin: ★
    example.com
Accept-Ranges: bytes


CloudFrontでのCORS設定手順

オリジンに CORS を設定した後、オリジンに必要なヘッダーを転送するように CloudFront ディストリビューションを設定します。


CloudFront側のCORS設定

「Distribution」「Distribution Settings」「Behaviours」を選択する

「Cache Based on Selected Request Headers」を「White List」にする
「Whitelist Headers」で「Origin」をAddする



オリジンが S3 バケットである場合は、通常、次のヘッダーを Amazon S3 に転送するように配信を設定する必要があります。

  • Origin
  • Access-Control-Request-Headers
  • Access-Control-Request-Method


オリジン側(接続先)のCROS設定(呼ばれる側の設定)

S3

Bucketを選択して、Permissionsタブに進みます。

2020年11月のコンソールのアップデートとあわせて、このCORS指定時の記法がXMLからJSONに変わりました。

JSON記法
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]
[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            "https://example.net",
            "https://*.example.net",
            "http://example.net",
            "http://*.example.net"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3000
    }
]


Apache

https://enable-cors.org/server_apache.html

<IfModule mod_headers.c>
  Header set Access-Control-Allow-Origin "*"
</IfModule>


Nginx

https://enable-cors.org/server_nginx.html

#
# Wide-open CORS config for nginx
#
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
     }
}


CORS問題となる詳細

CloudFrontではデフォルトでOriginヘッダ自体の転送をしている話〜Video.jsで発生するCORSエラーのトラブルを例にして | DevelopersIO

CloudFrontでのCORS設定、Originヘッダのオリジンへの転送を設定しておけばCORSエラーは回避できます。
ただトラブルになりやすい点として、設定を忘れてしまっていても、
ChromeなどOriginヘッダをリクエスト時に転送する環境だけでの再生であればCORSエラーは発生しません。
SafariのようなOriginヘッダをリクエスト時に転送しない環境が入り、
かつその環境が先にリクエストを行いキャッシュされる、となって初めてCORSエラーが発生する環境となります。

操作例

CloudFrontのキャッシュ無効化
Mac版のSafariを利用
リクエスト時にはOriginヘッダは付与されていません。
レスポンスにも、Access-Control-Allow-Originヘッダは含まれません。
エラーが発生しない。

CloudFrontのキャッシュ無効化
Mac版のChromeを利用
リクエスト時にOriginヘッダが付与されている。
レスポンスヘッダではAccess-Control-Allow-Originヘッダが含まれています。
エラーが発生しない。

ChromeのようにOriginヘッダが付与されているリクエストでアクセスがあったあと、
SafariのようにOriginヘッダが付与されていないリクエストがある、
初回アクセス時にAccess-Control-Allow-Originヘッダを含むレスポンスが返され、CloudFrontにキャッシュされます。
後続のリクエストでもこのキャッシュが使われ、レスポンスにはAccess-Control-Allow-Originヘッダが含まれる、という状況になりますね。
これだとCORSでの再生エラーなどは発生しない状況となります。

SafariのようにOriginヘッダが付与されていないリクエストのあとに、
ChromeのようにOriginヘッダが付与されているリクエストがあった場合です。
この場合は初回アクセス時のレスポンスにAccess-Control-Allow-Originヘッダは含まれません。
後続のリクエストもこのレスポンスを使用するため、
ChromeなどCORS対応でAccess-Control-Allow-Originヘッダが本来必要になる環境でも
Access-Control-Allow-Originヘッダなしのレスポンスとなり、
結果、CORSエラーが発生します。

CORSエラー

CORSエラーとなるのは、Originヘッダが付与されているリクエストをした際に、キャッシュされているAccess-Control-Allow-Originヘッダなしのレスポンスが返ってきた場合です。

aws/cloudfront/cors.txt · 最終更新: 2021/09/01 09:02 by kurihara

ページ用ツール