AWS S3とCloudFrontにCORSの設定をしてCSSファイルやJSファイルを配信する

2018.09.06

困ったこと

S3に配置したCSSファイルやJavaScriptファイルをCloudFront経由で利用しようとするとブロックされる。 FontAwesomeのファイルをCloudFront経由で読み込むようなWebアプリケーションを作ったら、アイコンが全部豆腐になってしまった。

CORSとは

CORSとは、「Cross-Origin Resource Sharing」の頭文字を取ったもの。 オリジン(Origin)とは、

  • スキーム(http://httpsなど)
  • ホスト名(example.comなど)
  • ポート番号(:3000など)

のこと。

これらは全て別オリジンということになる。

オリジンをまたいでAjax通信をすることは基本的に禁止されているが、それを許可するための仕組みがCORSである。

CORSの設定をするには

Ajaxリクエストを発行する側をサーバーA、Ajaxリクエストを受けてレスポンスを返すサーバーをBとしたとき、サーバーBのHTTPヘッダーに



Origin: http://example.com

のようにアクセスを許可したいオリジンを指定することでCORSの設定ができる。 この場合、サーバーBのコンテンツをAjax通信で取得できるオリジンはhttp://example.comとなる。 どのオリジンからでも参照できるようにするには、*を指定すればよい。

AWS S3のCORSの設定

AWS S3はマネージドサービスのため、ApacheやNginxのように設定ファイルを直接自分で編集することはできない。AWSマネジメントコンソールか、AWS CLIから操作をする必要がある。

HTTPとHTTPSで利用できるサイトの場合は、以下のように<CORSRule>ブロックを2つ書く。 HTTPのみ、もしくはHTTPSのみの場合は不要な方の<CORSRule>ブロックを削除すればOK。



<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://example.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>http://example.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

ちなみに2006-03-01という日付が見えるが、これは変更してはいけない。 AWS内でCORSの設定を管理するXMLのフォーマットにバージョンがあり、それを指定しているものなので変更すると動かなくなる。

AWS CloudFrontのBehaviorの設定

S3に置いたコンテンツをCloudFrontでキャッシュして配信する構成の場合、HTTPヘッダーもキャッシュする設定にしないとせっかく組んだCORSの設定が反映されない。

CloudFrontの設定画面から以下のように設定する。

  • ディストリビューションを選択する。
  • 「Cache Based on Selected Request Headers」で「WhiteList」を選択する。
  • 「Whitelist Headers」に「Origin」を追加する。

CloudFrontは設定を変更しても今キャッシュされているファイルが再度オリジンから取得されるわけではない。 そこで、コンテンツをオリジンから再取得するために以下のどちらかの操作をする必要がある。

サーバーサイドのフレームワークにはRuby on Railsを使っていて、Asset Pipelineを利用してCSSやJavaScriptをビルドしているので、1つ目の方法を基本的に使っている。

ただ、一度プリコンパイルしたCSS・JavaScriptファイルは変更しないとダイジェストが変わらないので、何かしらの変更をして、その後プリコンパイルを実行して、S3にアップロードするという流れになる。

追記:AWSマネジメントコンソールからCORSの設定が編集できないとき

AWS S3とCloudFrontにCORSの設定をしてCSSファイルやJSファイルを配信する

AWS CLIを使ってCORSの設定を変更できる。 詳しい手順は以下の記事にまとめた。