【セキュリティ】CORS とは

オリジンとは
オリジンとは、異なる Web アプリケーション同士でアクセスを制限するための境界。
オリジンの組み合わせは基本的に、「スキーム名 + ホスト名 + ポート番号」。
Web アプリケーションのオリジンが同じことを、「同一オリジン」と呼び、オリジンが異なることを、「クロスオリジン」という。

同一オリジンポリシーとは
一定の条件において、クロスオリジンのリソースへのアクセスを制限する仕組みを「同一オリジンポリシー」という。
例えば、https://site.example
のURLをブラウザで開いているとして、https://site.example
サーバーへのアクセスは同一オリジンのため成功する。
しかし、https://cross-origin.example
へのアクセスはクロスオリジンのため失敗する。
ブラウザは、デフォルトで同一オリジンポリシーを有効にしている。

クロスオリジンへアクセスしたい場合は
デフォルトでは同一オリジンポリシーにより、クロスオリジンへのアクセスは失敗するが、CORS という仕組みを利用すれば可能になる。

CORS とは
Cross-Origin Resource Sharing の略。
クロスオリジンへのリクエストを可能にする仕組みのこと。
通常、fetch 関数などでクロスオリジンへリクエストすると同一オリジンポリシーにより失敗する。
具体的には、クロスオリジンから受信したレスポンスのリソースへのアクセスが禁止されている。
しかし、レスポンスに付与されている HTTP ヘッダによってサーバーからアクセスしても良いと許可を与えられているリソースへはアクセスできるようになる。
ではどんな HTTP ヘッダをレスポンスに付与すれば良いのか。
Access-Controll-Allow-Origin
ヘッダを使う。
例えば、https://site.example
のURLをブラウザで開いているとして、https://site.example
サーバーへのアクセスは同一オリジンのため成功する。
しかし、何もしないと https://cross-origin.example
サーバーへのアクセスはクロスオリジンのため失敗する。
そこで https://cross-origin.example
サーバーからのレスポンスヘッダに以下のヘッダを付与することで、クロスオリジンへのアクセスが成功する。
Access-Controll-Allow-Origin: https://site.example
ちなみに、ワイルドカードを使えば全てのオリジンからアクセスを許可することができる。
Access-Controll-Allow-Origin: *
なお、Access-Controll-Allow-Origin
は単純リクエストに関する話。
単純リクエストではない場合は、プリフライトリクエストが必要。

単純リクエストとは
プリフライトリクエストの話に映る前に、単純リクエストとは何か整理する。
単純リクエストとは、<img>
や <link>
などリソースを取得する GET によるリクエストや、<form>
を使った GET または POST によるブラウザがデフォルトで送信できるリクエストのこと。
一方、fetch 関数などによってユーザーが任意の HTTP ヘッダを付与されていたり、PUT や DELETE といったサーバー内のリソースを変更・削除するような HTTP メソッドが使われていたりする場合は単純リクエストには含まれない。

プリフライトリクエスト
単純リクエスト以外のリクエストは、事前にリクエストしても問題ないかブラウザからサーバーに問い合わせを行う。
この事前の問い合わせ用のリクエストがプリフライトリクエストである。
プリフライトリクエストには、OPTIONS
メソッドが使われる。
プリフライトリクエストにより、メソッドが許可されていれば実行されるという仕組みである。