
CORSの理解が曖昧だったのでまとめてみた | #勉強記録
CORS(オリジン間リソース共有)の概要
サイト(異なるオリジン)間でデータをやり取りするための仕様
Cross-Origin Resource Shareringの略
「コルス」や「シーオーアールエス」と読まれる
CORSがなぜ必要か
結論
同一オリジンポリシーとの互換性を保ちながら、信頼できる接続先(別のオリジン:クロスオリジン)へのアクセスを許可するため
実現方法
サーバー側から返されるHTTPレスポンスに付与される一連のヘッダに許可する条件を記載する
条件を満たしたリクエスト
ブラウザは受信したリソースにJavaScriptによるアクセスを許可する
条件を満たしていないリクエスト
ブラウザは受信したリソースへのアクセスを禁止して、レスポンスを破棄する
CORSに関する用語
サンドボックス
ブラウザのセキュリティ機能の基本的な考え方の一つ
JavaScriptに採用されている
プログラムの「できること」を制限する環境(サンドボックス)を用意する
制約を用意することで、悪意のあるプログラムによって利用者に被害が及ばないようにする
JavaScriptのサンドボックスの機能制限は下記
ローカルファイルへのアクセスを禁止
プリンタなどのリソースの利用を禁止(画面表示は可能)
ネットワークアクセスの制限
同一オリジンポリシーという制限(後述)
同一オリジンポリシー
JavaScriptなどのクライアントスクリプトからサイトをまたがったアクセスを禁止するという制限
異なるホスト(オリジン)にあるJavaScriptからのアクセスは拒否される
同一オリジンとみなされる条件は下記
FQDN(URLのホスト)が一致
プロトコル(スキーム)が一致
http,httpsなど
ポート番号が一致

[CORSの種類]シンプルなリクエスト(単純リクエスト)
概要
リソースを取得するためのGETリクエストや、<form>要素を使ったGETまたはPOSTによるブラウザがデフォルトで送信できるリクエストのこと
「CORS-safelisted」に該当するHTTPメソッドやHTTPヘッダのみが送られるリクエストのこと
該当要件:CORS-safelistedとみなされるメソッドやヘッダ
リクエスト
GET
HEAD
POST
ヘッダー
Accept
Accept-Language
Content-Language
Content-Type(※以下のいずれか)
application/x-www-form-urlencoded
multipart/form-data
text/plain
サーバー側からのレスポンスに含めるヘッダ
Access-Control-Allow-Origin
アクセスを許可するオリジンを値とする
"*":すべてのオリジンからのアクセスを許可する
"https:sample.com"など、許可したいオリジンを明記することでリソースへのアクセスを制限できる
[CORSの種類]シンプルではないリクエスト
概要
シンプルなリクエスト以外のリクエストのこと
Content-Type:application/json も該当する
ブラウザは「プリフライトリクエスト」という問い合わせ用のリクエストをサーバーに事前に送付し、許可されている場合のみ本来のリクエストを送付する
プリフライトリクエスト
OPTIONSメソッドが使用される
プリフライトリクエストの確認結果によるブラウザ動作
許可されているリクエストであることが確認できた場合
本来のリクエストを送信する
許可されていないリクエストであった場合
本来のリクエストはサーバーに送信されない
サーバー側からのレスポンスに含めるヘッダ(プリフライトリクエストに対する応答)
Access-Control-Allow-Origin(※シンプルなリクエストと同じ)
Access-Control-Allow-Methods
リクエストに利用可能なHTTPメソッドの一覧
例)OPTIONS,POST
Access-Control-Allow-Headers
リクエストで送信可能なHTTPヘッダの一覧
例)Content-Type
Access-Control-Max-Age
プリフライトリクエストの結果をブラウザ側にキャッシュする時間(秒)
プリフライトリクエストがパフォーマンスのボトルネックとなるのを防ぐために設定する
適用例
ネットワーク回線が低速な環境
クロスオリジンへのリクエストを大量に送る場合
[CORSの種類]Cookie(認証情報)をリクエストに含める場合
概要
Cookieを送信する場合は、Cookieを含むリクエストを送信することを明示する必要がある
JavaScriptにおけるクロスオリジン通信では、通常、Cookieは送信されない
外部サーバーへの機密情報漏えいリスクを下げるため
fetch関数によるクライアント側からのリクエスト送信
credentialsオプションに"include"を設定する
credentialsオプションの値の種類は下記
omit:Cookieを送信しない(デフォルト値)
same-origin:同一オリジンのみCookieを送信する
include:オリジンに関係なく、常にCookieを送信する
XMLHttpRequestでのクライアント側からのリクエスト送信
withCredentialsプロパティにtureを設定する
サーバー側からのレスポンスに含めるヘッダ
Access-Control-Allow-Origin
必ず明示的にオリジンを指定する
Originヘッダの値をAccess-Control-Allow-Originの値にそのままセットするような実装は、すべてのオリジンを許可することと変わらないため危険である
Access-Control-Allow-Credentials
true を値に設定する
このヘッダおよび値がレスポンスに含まれていない場合、Cookie付きのリクエストは破棄される