web-dev-qa-db-ja.com

正しいS3 + Cloudfront CORS構成?

私のアプリケーションは画像をS3に保存し、Cloudfrontを介してそれらをプロキシします。新しいS3 CORSサポートを使用して、クロスオリジンポリシーを持つHTML5キャンバスメソッドを使用できるようになりましたが、S3とCloudfrontを正しく構成できないようです。画像をキャンバス要素に変換しようとすると、「不明なエラー:SECURITY_ERR:DOM例外18」が引き続き発生します。

ここに私が持っているものがあります:

S3

<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>MY_WEBSITE_URL</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
  <CORSRule>
    <AllowedOrigin>MY_CLOUDFRONT_URL</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    </CORSRule>
  </CORSConfiguration>

Cloudfront

起源

Origin Protocol Policy: Match Viewer

HTTP Port: 80

HTTPS Port: 443

行動

Origin: MY_WEBSITE_URL

Object Caching: Use Origin Cache Headers

Forward Cookies: None

Forward Query Strings: Yes

ここに足りないものはありますか?

更新:ヘッダーを変更してみました

<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>

この質問に基づいて Amazon S3 CORS(クロスオリジンリソース共有)およびFirefoxクロスドメインフォントの読み込み

まだ行かない。

更新:リクエストに関する詳細

Request
URL:https://d1r5nr1emc2xy5.cloudfront.net/uploaded/BAhbBlsHOgZmSSImMjAxMi8wOS8xMC8xOC81NC80Mi85NC9ncmFzczMuanBnBjoGRVQ/32c0cee8
Request Method:GET
Status Code:200 OK (from cache)

更新

多分私の要求は正しくなかったと思うので、CORSを有効にしてみました

img.crossOrigin = '';

しかし、その後、イメージがロードされず、「クロスオリジンリソース共有ポリシーによりクロスオリジンイメージのロードが拒否されました」というエラーが表示されます。

53
kateray

2014年6月26日、AWSは 適切なVary:CloudFrontでのOriginの動作 をリリースしました。

  1. 以下を含むS3バケットのCORS設定を設定します

    <AllowedOrigin>*</AllowedOrigin>

  2. CloudFront->配布->このオリジンの動作

    • 許可されるHTTPメソッド:+ OPTIONS
    • キャッシュされたHTTPメソッド+ OPTIONS
    • 選択したリクエストヘッダーに基づくキャッシュ:Originヘッダーをホワイトリストに登録します。
  3. CloudFrontが新しいルールを伝播するまで、約20分間待ちます

これで、CloudFrontディストリビューションは、さまざまなクライアントOriginヘッダーのさまざまな応答(適切なCORSヘッダーを使用)をキャッシュする必要があります。

109
Brett

@ Brett's answer を補完します。 CloudFrontのCORS および S3のCORS を詳述するAWSドキュメントページがあります。

そこで詳細な手順は次のとおりです。

  1. S3バケットでPermissions-> CORS configurationに移動します
  2. エディターでCORSのルールを追加します。<AllowedOrigin>ルールは重要です。設定を保存します。 enter image description here
  3. CloudFrontディストリビューションで動作->動作を選択->編集
  4. OPTIONS応答をキャッシュするかどうかに応じて、AWSに従って2つの方法があります。
  • OPTIONS応答をキャッシュする場合は、次を実行します。
    • OPTIONS応答のキャッシュを有効にするデフォルトのキャッシュ動作設定のオプションを選択します。
    • 次のヘッダーを転送するようにCloudFrontを構成します:Origin、Access-Control-Request-Headers、およびAccess-Control-Request-Method。
  • OPTIONS応答をキャッシュしたくない場合は、Originヘッダーを、Originに必要な他のヘッダーと一緒に転送するようにCloudFrontを構成します

enter image description here

そして、S3を使用したCloudFrontのCORSが機能するはずです。

24

更新:これは、CloudFrontの最近の変更には当てはまりません。イッピー!詳細については、他の回答を参照してください。コンテキスト/履歴のためにここに残しておきます。

問題

CloudFrontはCORS 100%をサポートしていません。問題は、CloudFrontがリクエストへの応答をキャッシュする方法です。その後、同じURLに対する他のリクエストは、キャッシュされたリクエストになりますOriginに関係なく。それに関する重要な部分は、Originからの応答ヘッダーが含まれていることです。

CloudFrontがOrigin: http://example.comからキャッシュされたものを持つ前の最初のリクエストには、応答ヘッダーがあります:

Access-Control-Allow-Origin: http://example.com

Origin: https://example.comからの2番目の要求(HTTPではなくHTTPSであることに注意してください)には、次の応答ヘッダーもあります。

Access-Control-Allow-Origin: http://example.com

CloudFrontがURLに対してキャッシュしたものだからです。これは無効です。ブラウザコンソール(少なくともChrome))にCORS違反メッセージが表示され、問題が発生します。

回避策

推奨される回避策は、異なるオリジンに対して異なるURLを使用することです。トリックは、Originごとに1つのキャッシュされたレコードがあるように、異なる一意のクエリ文字列を追加することです。

したがって、URLは次のようになります。

http://.../some.png?http_mysite.com
https://.../some.png?https_mysite.com

この種の機能は動作しますが、クエリ文字列を交換することで、だれでもサイトの動作を低下させることができます。そうでしょうか?おそらくそうではありませんが、この問題のデバッグは非常に面倒です。

正しい回避策は、CORSを完全にサポートするまで、CloudFrontをCORSで使用しないことです。

実際

CORSにCloudFrontを使用する場合は、CORSが機能しない場合に機能する別の方法にフォールバックします。これは常にオプションとは限りませんが、現在はJavaScriptでフォントを動的に読み込んでいます。 CloudFrontへのCORSベースのリクエストが失敗した場合、フォントへのサーバー側プロキシにフォールバックします(Originをまたいではありません)。このように、CloudFrontが何らかの理由でフォントのキャッシュレコードが不正に取得されても、物事は機能し続けます。

5
Cymen

あなたの問題が何であるか完全にはわかりませんが:

https://forums.aws.Amazon.com/thread.jspa?messageID=37751

cORS、S3、Cloudfrontに関する私の問題のいくつかに答えました。

また、バケット内の一部のアセットが正しいCORSヘッダーで返され、一部が返されないこともわかりました。アセットを無効にした後、それらはすべて正しいヘッダーで戻ってきましたが、一部が無効化を必要とし、他が同じタイプの同じバケットを同時にアップロードしたので、なぜそうしなかったのかわかりません:(

2
Jim