⚠️ 記事内に広告を含みます。

CORSとは?できるだけ簡単に解説

CORSとは?

理解が難しいCORSに関して簡単に説明します。

CORSを簡単に解説

CORS (Cross-Origin Resource Sharing) オリジン間リソース共有はMozillaのホームページによると

追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組み https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

オリジン間リソース共有 (CORS) – HTTP | MDN https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

と説明されています。

これだけでは意味がわからないと思いますので、詳しく見ていきます。

登場用語の整理

オリジン

オリジンはユーザのブラウザが要求するデータを送信してくれる配信元のサーバのことです。

ユーザのブラウザがリクエストしたデータを送ってくれるのがオリジン(サーバ)

WEBアプリ

WEBアプリはインターネットを見るブラウザ上で利用できるアプリです。WordpressのブログサイトもWEBアプリの一つなので、単純なウェブサイトと捉えても問題ないです。

異なるオリジン

ユーザが使ったWEBアプリがあるオリジンとは別のサーバからデータを取得しなければならない時、別のオリジンは元のオリジンとは異なるオリジンです。

なぜわざわざ、別のオリジンから取得してるのか?

これは様々な理由がありますが、

  • 負荷分散
    • 大容量な画像や動画のダウンロードで負荷をアプリサーバにかけたくない
  • 機能分離
    • アプリサーバとコンテンツ配信サーバを機能的に分離したい
  • 他アプリとの共用
    • アプリAやアプリBで利用しているコンテンツサーバを共用したい

負荷を分散したり、機能的にオリジンを分けたいといった理由で分けることがあります。

しかし、デフォルトでは別オリジンからデータを取得することはセキュリティ上、禁止されています

CORSは制約を回避するため

CORSがない場合は別オリジンにある画像の取得ができません。

別オリジンから画像を取得する場合は、別オリジンのhttps://static.example.comをCORSで許可する設定が必要です。

同一オリジンの基準

同一オリジンとは、同じスキーム、ホスト、ポート全てが一致するものを指します

スキーム:http, htpps

ホスト:example.com

ポート:80, 443, 8080

別オリジンへのリクエストが禁止されている音はCSRF攻撃という脅威があるからです。
CSRF(クロスサイトリクエストフォージェリ)は全く違う悪意のあるサイトURLにアクセスしたときにクロスサイトリクエストにより別のサイトの情報を抜き取られたり、設定変更などが行われてしまうことです。

会員制Aサイト(https://member.example.com)にログインしている状態

迷惑メールのURL(https://csrf.example.com)をクリック

知らないサイトに誘導(https://csrf.example.com)

迷惑メールのURL中に会員制Aサイトhttps://member.example.comに対してリクエストを送信するコードが埋め込まれていて実行してしまう

ユーザはcsrf.example.comにアクセスしただけだが、会員制Aサイトのプロフィール情報が攻撃者の元に送信されたり、会員制Aサイトで不正にカード利用されたりする可能性がある

この一連の攻撃を防止するには異なるオリジンへのリクエストをデフォルトで禁止するのが有効です。

CORSを設定する

MmdnのドキュメントにあるようにCORSではhttpヘッダーを利用します。
HTTPヘッダーを使ってリソース取得を許可するオリジンを指定します。

Access-Control-Allow-Origin:のヘッダーに*を設定 → 全許可

httpヘッダーにCORSに利用する情報を追記します。

例えば、Access-Control-Allow-Origin: *というヘッダーは全オリジンへのリクエストが許可されています。

特定のオリジンのみを許可する

コンテンツサーバ: https://static.example.comに対して、アプリサーバ:https://example.com からリクエストが飛ぶとします。

コンテンツサーバstatic.example.comは信頼できるhttps://example.comのクロスサイトリクエストは許可したいが、それ以外のhttps://akui.example.comなどは禁止したいという場合は以下のようにAccess -Control-Allow-Originヘッダーに記載します。

Access-Control-Allow-Origin: https://example.com

CORSの2つのシナリオ

次に具体的なCORSのシナリオについて説明します。

元オリジン:https://example.com
別オリジン:https://static.example.com とします。

クロスオリジンリクエストには以下のシナリオがあります。

  • 単純リクエスト
  • プリフライトリクエスト

単純リクエスト

単純リクエストは下記の条件を満たすものです

  • メソッド:GET, HEAD, POST
  • ヘッダー: Accept, Accept-Language, Content-Language, Content-Type, Range, (Connection User-Agent)
    • Content-Typeはapplication/x-www-form-urlencoded, multipart/form-data, text/plainのみ
  • ReadableStreamオブジェクト未使用
  • XMLHttpRequest.upladプロパティから返されるオブジェクトにイベントリスナーが登録されていない

元のオリジンexample.comから別のオリジンのリソースを参照する場合には、別オリジンhttps://static.examplec.comはリクエストヘッダのAccec-Control-Allow-Originを参照して許可オリジンかどうか判断します。

1. クライアントが元オリジンhttps://example.comにアクセス
2.元オリジンは自身がオリジンであることを示すorignヘッダーを付加してクライアントに返す

Origin: https://example.com

3. クライアントは元オリジンから受け取ったJavaScriptの処理により、別オリジンhttps://static.example.comのリソースを受け取りに別オリジンにリクエストを送信する
4. 別オリジンhttps://static.example.comはoriginヘッダーを見る
5. 別オリジンはexample.comは許可しているのでAccess-Contral -Allow -Originヘッダーを付加してクライアントにレスポンスを返す

Access-Control-Allow-Origin: https://example.com

6. これでクライアントは別オリジンのデータを取得できた

Webブラウザがサーバにデータをくれという要求をリクエスト
サーバがリクエストに応答してデータを返すのがレスポンス
HTTPプロトコルを利用する

プリフライトリクエスト

プリフライトリクエストは別のオリジンにリクエストを送信する前に確認のリクエストを送信する方法です(許可オリジンか確認するやり取りが一往復増える)。

単純リクエストの条件外では「プリフライトリクエスト」で行われます。

プリフライトリクエストでは、はじめにOPTIONメソッドを別オリジンに送信して信頼できるオリジンかを判断します。

1. クライアントは別オリジンにOPTIONSメソッドでリクエストを送信
 OPTIONSメソッドには以下3つのヘッダーを含む(値は例)
 ・Origin:https://example.com
 ・Access-Control-Request-Method:POST
 ・Access-Control-Request-Headers: X-PINGOTHER, Content-Type
2.プリフライトリクエストを受け取ったサーバ(https://static.example.com)はレスポンスを返す(許可の内容が書かれれてる)OKの場合は2xxの応答がかえる(200や204)
 ・Access-Control-Allow-Origin:https://example.com
 ・Access-Control-Request-Method:POST, GET, OPTIONS
 ・Access-Control-Request-Headers: X-PINGOTHER, Content-Type
3. ブラウザはプリフライトリクエストの結果、許可されている場合は本来のPOSTを送信してリソースを取りにいく
4.別オリジンはレスポンスでリソースを返却する

Access-Control-Allow-Originにはカンマ区切りなどで複数の値を入れることができません。
複数入れる場合はバックエンド側のWebサーバ設定で正規表現を使って判断し、マッチしたAccess-Control-Allow-Originoriginをヘッダーにセットして返却というように設定します。

https://qiita.com/KWS_0901/items/df60a4c19a30e63e0f00

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です