はじめに
APIを作っているとほぼほぼCORSに関する実装を行うことになるが、登場してくるリクエストヘッダやレスポンスヘッダの名前が少々紛らわしくて覚えづらい。
そこでCORSとは何か?から始まって一連のやりとり、及び必要なリクエストヘッダ・レスポンスヘッダの名前や設定値についてメモを取ることとする。
CORS
XHRでは、異なるドメインに対してアクセスを行い、レスポンスデータを読み込むことができない(同一生成元ポリシー)。生成元はURI中のスキーム・ホスト・ポート番号の組み合わせで判断される。
http://example.com と http://example.com:8080 は異なる生成元となる。
JSONP
という手法もあるが、これはある種ハックでありセキュリティ上の問題も多い。
そこで異なる生成元にアクセスするための手法としてクロスオリジンリソース共有(CORS)という仕様が策定された(2014/1 正式にW3C勧告)。
以下、CORSの基本的なやりとりを記載する。
クライアントから Origin
リクエストヘッダを送る
Origin: http://www.example.com
Access-Control-Allow-Origin
レスポンスヘッダ
Access-Control-Allow-Origin
にOrigin
ヘッダと同じ生成元を入れてレスポンスすると、ブラウザはそのレスポンスを受け入れることになる。この値に*
を指定すると、どこからでも読み込めることを明示できる。
ブラウザがレスポンスを受け入れることができるということは、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レスポンスヘッダを発行する必要がある。
Cookie
やAuthentication
ヘッダを使ってユーザ認証情報をクライアントが送ってきた場合、サーバは
Access-Control-Allow-Credentials: true
として、「認証情報を認識しています」ということをクライアントに返信する必要がある。これがなかった場合、ブラウザは受け取ったレスポンスを拒否してしまう。
また各ブラウザのXHRはクッキーなどの認証情報を送る際にはwithCredentials
プロパティをtrue
にセットしなくてはならない。