Edited at

CORS関連、これだけ知っとけばまぁ大丈夫

More than 1 year has passed since last update.


はじめに

APIを作っているとほぼほぼCORSに関する実装を行うことになるが、登場してくるリクエストヘッダやレスポンスヘッダの名前が少々紛らわしくて覚えづらい。

そこでCORSとは何か?から始まって一連のやりとり、及び必要なリクエストヘッダ・レスポンスヘッダの名前や設定値についてメモを取ることとする。


CORS

XHRでは、異なるドメインに対してアクセスを行い、レスポンスデータを読み込むことができない(同一生成元ポリシー)。生成元はURI中のスキーム・ホスト・ポート番号の組み合わせで判断される。


http://example.comhttp://example.com:8080 は異なる生成元となる。


JSONPという手法もあるが、これはある種ハックでありセキュリティ上の問題も多い。

そこで異なる生成元にアクセスするための手法としてクロスオリジンリソース共有(CORS)という仕様が策定された(2014/1 正式にW3C勧告)。

以下、CORSの基本的なやりとりを記載する。


クライアントから Originリクエストヘッダを送る

Origin: http://www.example.com


Access-Control-Allow-Originレスポンスヘッダ

Access-Control-Allow-OriginOriginヘッダと同じ生成元を入れてレスポンスすると、ブラウザはそのレスポンスを受け入れることになる。この値に*を指定すると、どこからでも読み込めることを明示できる。

ブラウザがレスポンスを受け入れることができるということは、XHRの結果を読み込んで何らかの処理をするJavascriptのコードを書くことができるということ。


プリフライトリクエスト

生成元をまたいだリクエストを行う前に、そのリクエストが受け入れられるかどうかを事前にチェックする。以下の場合に必要になる。


  • 利用するHTTPメソッドがSimple Method(HEAD/GET/POST)以外である

  • 以下に示すヘッダ以外を送信しようとしている


    • Accept

    • Accept-Language

    • Content-Language

    • Content-Type



以下に示す以外のメディアタイプをContent-Typeに指定している。


  • application/x-www-form-urlencoded

  • multipart/form-data

  • text/plain

OPTIONメソッドを使って送信される


プリフライトリクエストのレスポンス

ヘッダ
意味

Access-Control-Allow-Method
許可されるメソッドの一覧

Access-Control-Allow-Headers
許可されるヘッダの一覧

Access-Control-Max-Age
プリフライト情報のキャッシュを保持して良い時間


CORSとユーザ認証情報

CORSではユーザ認証情報(Credential)を送信する際には、サーバサイドは追加のHTTPレスポンスヘッダを発行する必要がある。

CookieAuthenticationヘッダを使ってユーザ認証情報をクライアントが送ってきた場合、サーバは

Access-Control-Allow-Credentials: true

として、「認証情報を認識しています」ということをクライアントに返信する必要がある。これがなかった場合、ブラウザは受け取ったレスポンスを拒否してしまう。

また各ブラウザのXHRはクッキーなどの認証情報を送る際にはwithCredentialsプロパティをtrueにセットしなくてはならない。


参考文献

Web API The Good Parts