CORS
CORS
Cross-Origin Resource Sharing
あるオリジンから取得したリソースが、それ以外のオリジンにリクエストを送ることを許可する<ブラウザの>仕組み
curl とかだとそもそもないよ
オリジン
WEB コンテンツリソースの提供元
スキーム、ホスト、ポートの組み合わせで表現される
CORS の目的
善良なクライアント(ブラウザ)が想定外の悪意ある動作(XSS, CSRF)をしないように守っているパターン
CORS の実装
あるのリソースのオリジン(https://example.com)が、それとは別のオリジン(https://api.example.com)にアクセスするとき、ブラウザは自動で以下のようなOriginフィールドを HTTP リクエストに付与する
Origin: https://example.com
これを受け取ったapi.exapmple.comのサーバは以下のようなレスポンスを返す必要がある
code:http
Access-Contral-Allow-Hedaers: "X-Requested-With, Content-Type"
Access-Contral-Allow-Originは指定したオリジンのコンテンツに対して自身のオリジンへのアクセス許可をブラウザに与える
ここではhttps://example.comをオリジンとするリソースに対して、https://api.example.comのリースへのアクセス or 変更を許可している
これを返す必要性は下記に
Access-Contral-Allow-Originを返す必要性
Q: これをわざわざブラウザに返す必要性なくない?単にOriginをサーバ側で確認するだけで良くない?
A: 後方互換性のため
WEB 周りの設計の理念に以下のようなものがある
「コンテンツ作成者またはサイト管理者が、既存のセキュリティ保護レベルを維持するために、新規または追加のセキュリティ保護を実装することを要求してはならない。」
昔 WEB 世界では別オリジンから JSON リクエストが飛んでくる、みたいなことを想定していない?
ブラウザはそんなことはしないと思っている?
そんな旧世界で生きているサーバはリクエストにOriginがあっても無視してしまい、別オリジンからのリクエストに対して正直に返してしまう
その対策をすべての旧世代サーバに対して行うのは無理
そこで CORS が通用する新世代のサーバかどうかをクライアントでも確認する
具体的には、返されたAccess-Contral-Allow-Originの条件を満たす or そもそもこれが存在するかを確認し、良ければリクエストを許可
Q: しかしこの場合、サーバが CORS 制御に対応していることを表明できれば十分で、Access-Contral-Allow-Originを返す必要性はないのではないか
A: 「サーバーサイドスクリプト(PHP、ASP、CGIなど)を使用せずに、クロスオリジンGETリクエストのサポートをIISとApacheに展開できること。」というルールがあり、リクエストの Originを動的に見ることなく、静的に CORS 制御を行う必要がある
preflight リクエストの存在儀
上記のやり方ではPUTなどの場合、結局サーバ側でも実行されてしまう
そこで、preflight であらじめ確認
CORS の設計意図