同一オリジンポリシーとCORS


よく見るエラー

Access to XMLHttpRequest at 'http://example:3000' from origin 'http://localhost:8080' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

同一オリジンポリシー(Same-Origin Policy)とは

  • CSRF等の攻撃を防ぐため、異なるオリジンのリソースへのアクセスに制約をかける考えかた。

同一オリジンの判定

  • プロトコル、ホスト、ポート番号の組み合わせが等しい場合は、同一オリジンとなる。

 具体例として http://www.example.com に対しては、

 http://www.example.com/example.png // 一致(パスが異なるだけ)
 https://www.example.com/example.png // スキーム不一致
 http://www2.example.com/example.png // ホスト不一致
 http://www.example.com:3000/example.png // ポート不一致

IEの場合は以下の二つの例外があり。
  • 信頼済みゾーン : 双方のドメインが高く信頼されたゾーン (企業のドメインなど) である場合は、同一オリジンの制限が適用されない。
  • ポート番号 : 同一オリジンの確認要素にポート番号を含まない。

同一オリジンポリシーの制約を受けるWebAPI

  • XMLHttpRequest
  • Canvas
  • Web Storage
  • X-Frame-Options

同一オリジンポリシーの制約を受けないリソース取得

  • script // スクリプト
  • img, video, audio // メディア
  • object, embed, applet // プラグイン
  • frame, iframe // 別サイトのコンテンツ
  • link, CSS(font-face): // CSS、Webフォントなど

CORS(Cross-Origin Resource Sharing)とは

  • 異なるオリジン間でのリソース共有の手法
  • 新たなリクエストヘッダーをサーバー側で付加することで作用する。
Access-Control-Allow-Origin: https://example.co.jp  // 特定のサイトを許可する
Access-Control-Allow-Origin: *   // 全てのサイトを許可する
Access-Control-Allow-Headers "X-Requested-With, Origin, X-Csrftoken, Content-Type, Accept"

CORS対応(単純リクエストの場合)

以下の条件を全て満たす場合、クロスオリジンのリクエストは受付可能

  • HTTPメソッドが下記のいずれか。
    • GET
    • POST
    • HEAD
  • HTTPヘッダに下記以外のフィールドが含まれない。
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • Content-Typeの値は下記のいずれか。
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

CORS対応(プリフライトリクエストの場合)

単純リクエストと異なる場合、プリフライトリクエスト (Preflight Request)を先に送り、
実際にリクエストしても良いか確認する。
以下の場合、標準外の Ping-Other HTTP リクエストヘッダーを設定しているので、
プリフライトリクエストの通信が先に行われる。

参考:https://developer.mozilla.org/ja/docs/Web/HTTP/CORS