CORSに関して
GW明けから仕事でWeb開発を行うことになりそうなので、リハビリを兼ねてお勉強しました。
テーマはタイトルの通りです。
CORSとは
オリジン1をまたいでリソースをAPIなどを通して共有する仕組みをCross-Origin Resource Sharing(以下CORS)と呼びます。
オリジンをまたいだ通信のことを クロスオリジン
と呼びます。
簡単に説明すると、クライアントからサーバにアクセスする前の権限確認プロトコルです。
アクセス制御フローに関して
単純なリクエストと、プリフライトリクエスト(後述)を送信するリクエストがあります。
単純リクエスト
以下の条件を満たすリクエストです。
- メソッドがGET、HEAD、POSTのどれか
- ヘッダーがAccept、Accept-Language、Content-Language、Content-Type以外含まない
- Content-Typeを含む場合、その値は以下のどれか
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
単純リクエストの場合、Fetch API(HTTPリクエストを発行するAPI)にcorsフラグを立てることよって通信可能になります。
レスポンスヘッダーでは、 Access-Control-Allow-Origin
を返信しています。
これを設定することによって、リソースの制限をかけることができます。
プリフライトリクエスト
上記以外のリクエストでは、 プリフライトリクエスト
が必要になります。
プリフライトリクエストとは、OPTIONSメソッドを用いて、送信先が安全かどうか確かめるためのリクエストです。
プリフライトリクエストのレスポンスとして、以下のものが含まれている必要があります。
サーバは、プリフライトリクエストを受けて、サーバが許可する通信内容をクライアント側に伝えます。
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Allow-Credentials
- Cookieなどの資格情報をサーバが受け取ることができる場合のみ付与される
- Access-Control-Expose-Headers
- レスポンスの一部として、どのヘッダーを公開するか列挙されている
プリフライトリクエストは通信するたびに毎回送信されるわけではなく、 Access-Control-Max-Age
で一定期間キャッシュすることによって省略できます。
Cookieの取り扱いについて
クロスオリジンの通信では、デフォルトではCookieの送受信はしません。
Cookieの送受信を可能にするには以下2つの条件が必要になります。
- クライアントで送信することが設定されている
- Cookieの送受信をサーバが許可している
まとめ
CORSは、クロスオリジンの通信を安全(?)にするための仕組みです。
リクエストによっては、プリフライトリクエストを事前に送信する必要があります。
実際に設定する場合は、クライアントサイド(何を許可してもらいたいか)とサーバサイド(何を許可しているか)の設定が必要です。
出典
[1] オリジン間リソース共有(CORS) (MDN Web Docs)
[2] なんとなく CORS がわかる...はもう終わりにする。(Qiita)
[3] ”Real World HTTP”(第2版)(オライリー・ジャパン)