Open1

S3とCloudfrontを使った際にCORSエラーを解消する方法

okita kamegorookita kamegoro

S3

CORS のエラーでは大抵このような表示がされている。

Access to font at '...' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

つまり、サーバーサイドは Access-Control-Allow-Origin ヘッダーを付与してクライアント側に返却すれば良い。

S3 での CORS の設定は下記の URL で解説されている。

これらを参考にすると、やり方は以下のようになる

  1. AWS のコンソールから S3 の対象となるバケットを選択する
  2. バケットのタブに「アクセス許可」があるのでクリック
  3. 下部にある「Cross-Origin Resource Sharing (CORS)」の「編集」ボタンをクリック
  4. 下記のようにルールを JSON で設定する (S3 のルールは JSON でのみ設定可能)
[
    {
        "AllowedHeaders": [
            // * で全てを対象にしても、AWSにリクエストを送信する際に利用するヘッダーを登録してもよい。
            // S3で必要になるヘッダーは 認証用のAuthorizationくらいだと思うので、それのみを付与してもよい
            "*"
        ],
        "AllowedMethods": [
            // S3の用途は基本的にリソースの取得となるため下記の2つがあれば良い
            "GET",
            "HEAD"
        ],
        "AllowedOrigins": [
            // S3のデータを取得したいサイトのドメインを記載する
            "example.com"
        ],
        "ExposeHeaders": [
            // レスポンスヘッダーに載せたいものを記述する
            "Access-Control-Allow-Origin"
        ]
    }
]

デバッグには curlを使うと便利。

以下のコマンドを実行すると、 -H: リクエストヘッダーの付与と -i: レスポンスヘッダーの取得、 --head: リクエストヘッダーのみの確認
が行える。

$ curl -i "[s3のリソースを取得したいURL]" -H "Origin: [アクセス基になるドメイン]" --head
# 例
$ curl -i "https://example.s3.ap-northeast-1.amazonaws.com/index.html" -H "Origin: example.com"

例えば、上記で示したような S3 の設定の場合、デバッグすると以下のようになる

Origin を example.com とした場合

curl -i "https://example.s3.ap-northeast-1.amazonaws.com/index.html" -H "Origin: example.com"

> HTTP/1.1 200 OK
> x-amz-id-2: 56NMI2wLWeP4uKWo6RCuMeyOQ6t3VF+eKu3HlHrOidLKE/RXYVPkjnpsCGJOYuGOJM/Veab3vi0=
> x-amz-request-id: 86DPA6HH5M1KZPDE
> Date: Wed, 13 Jul 2022 13:44:28 GMT
> Access-Control-Allow-Origin: example.com
> Access-Control-Allow-Methods: GET, HEAD
> Access-Control-Expose-Headers: Access-Control-Allow-Origin
> Access-Control-Allow-Credentials: true
> ....以下略

このように Access-Control-Allow-Origin: example.com, Access-Control-Allow-Methods: GET, HEADなどが付与されている

Origin を 他の オリジン にした場合 (example.com:8080hogehoge.com)

curl -i "https://example.s3.ap-northeast-1.amazonaws.com/index.html" -H "Origin: hogehoge.com"

> HTTP/1.1 200 OK
> x-amz-id-2: eHTuGit4mAH3pTf0/bLJPkVdM6Pj9+vYUGrEViH20jsnXqe/rMB7Lgjz3i4eNVMjQH2fOQOM7TM=
> x-amz-request-id: W0YF7BYHTHJSW01H
> Date: Wed, 13 Jul 2022 13:46:47 GMT
> Last-Modified: Tue, 24 May 2022 11:12:00 GMT
> ... 以下略

このように、レスポンスとしてほしい Access-Control-Allow-Origin がない状態になる。
このような状態だと、ブラウザは CORS エラーを吐いてしまう。