田んぼ

主に近況について書いていきます

CORSに関して

GW明けから仕事でWeb開発を行うことになりそうなので、リハビリを兼ねてお勉強しました。
テーマはタイトルの通りです。

CORSとは

オリジン1をまたいでリソースをAPIなどを通して共有する仕組みをCross-Origin Resource Sharing(以下CORS)と呼びます。
オリジンをまたいだ通信のことを クロスオリジン と呼びます。
簡単に説明すると、クライアントからサーバにアクセスする前の権限確認プロトコルです。

CORSにより、CSRF2を防ぐことができるようです3

アクセス制御フローに関して

単純なリクエストと、プリフライトリクエスト(後述)を送信するリクエストがあります。

単純リクエス

以下の条件を満たすリクエストです。

  • メソッドが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-Request-Method
  • Access-Control-Request-Headers
  • Origin

サーバは、プリフライトリクエストを受けて、サーバが許可する通信内容をクライアント側に伝えます。

  • 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つの条件が必要になります。

  1. クライアントで送信することが設定されている
  2. Cookieの送受信をサーバが許可している

まとめ

CORSは、クロスオリジンの通信を安全(?)にするための仕組みです。
リクエストによっては、プリフライトリクエストを事前に送信する必要があります。
実際に設定する場合は、クライアントサイド(何を許可してもらいたいか)とサーバサイド(何を許可しているか)の設定が必要です。

出典

[1] オリジン間リソース共有(CORS) (MDN Web Docs)
[2] なんとなく CORS がわかる...はもう終わりにする。(Qiita)
[3] ”Real World HTTP”(第2版)(オライリー・ジャパン


  1. URLのプロトコル、ホスト、ポートによって定義され、これらがすべて一致したときに、同じオリジンと呼ばれる。

  2. ユーザを騙し、意図しないリクエストをサーバに送信させる。リクエス送信先で対策をしていない場合、サーバが意図しない処理を実行してしまう。

  3. このような記事もあり、なるほどなぁと