CORS (Cross-Origin Resource Sharing) とは何だろうか?
スパイ映画では、警備員は 暗号化された 方法で情報を伝達します。彼らは主に、敵の手に渡った場合に自分たちに対して利用できる情報を送信しているため、情報を受け取る人が信頼できる当事者であることを確認する必要があります。当該情報を送信する者も同様とします。送信者と受信者が信頼できる場合、情報の信頼性と安全性が保証されます。
このシナリオのレプリカはブラウザと Web サーバー間の通信で発生し、同一生成元ポリシーと呼ばれます。

同一生成元ポリシーとは何ですか?
Web ページが別の Web サイトのリソースにアクセスできないことに気づいたことがありますか?これは、Web ページを提供するドメインとは異なるドメインのリソース (Cookie、スクリプト、その他のデータなど) に Web ページがアクセスすることを防ぐ Web ブラウザーのセキュリティ機能である Same-Origin ポリシーによるものです。
オリジンは、URL のプロトコル、ドメイン、ポート番号の組み合わせによって定義されます。 Chrome、Firefox、Safari、Edge を含むほとんどのブラウザは、データを安全に保つために同一生成元ポリシーを実装しています。

さて、なぜこのポリシーが必要なのでしょうか? これを理解するために、インターネットがどのように機能するかを見てみましょう。 Web サイトにアクセスすると、ブラウザーがその Web サイトをホストするサーバーにリクエストを送信し、サーバーはページの表示に必要なリソースを送り返すことで応答します。これらのリソースには、HTML、CSS、JavaScript、画像が含まれる場合があります。
Web ページが他のドメインにリクエストを行うこともできると想像してください。スパイ映画の前提を続けると、別の機関の秘密工作員が、別の組織または国の工作員と連絡を取り、アクセスを要求し、情報を共有したいと考えています。この機会が与えられると、後の組織は大きなセキュリティ脆弱性にさらされることになります。機密情報を盗み、損害を与える可能性があります。
この問題に正確に対処するために、同一生成元ポリシーが導入されています。 SOP についてはいくつかの誤解がありますが、異なるオリジンからリソースをロードしたり、別のオリジンに情報を送信したりできないという意味ではありません。
ただし、SOP は、スクリプト、CSS、iframe、画像、ビデオなどのさまざまなリソース間のアクセスと対話を制限するルールを設定します。これは、Web ページを独自のドメイン内に保持し、他のドメインからのリソースにアクセスできないようにするガードのようなものです。
これにより、データを盗んだり、望ましくないアクションを実行させたりする可能性のある悪意のある攻撃から保護されます。

CORSとは何ですか?
実際のケースでは、セキュリティ担当者が、セキュリティの手段として通信は担当者間でのみ行われるべきであるというルールを与える場合、これは同一生成元ポリシーに似ています。ただし、場合によっては外部とのやり取りが必要になる場合もあります。あるいは、他のセキュリティ組織の職員と協力して、そのために別のセキュリティ対策を導入して、その職員 を検証する こともできます。この検証は、関係する工作員に応じてさまざまな方法で行われます。インターネット上の通信の場合、 CORS は 、リソースの起源が異なるため、ブラウザーが本来アクセスできないリソースにアクセスできるようにするメカニズムです。
Cross-Origin Resource Sharing (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで実行されている Web アプリケーションが別のオリジンから選択されたリソースにアクセスできるようにブラウザーに指示するメカニズムです。
私は起源について何度か話しましたが、おそらくそれが何を意味するのか疑問に思っているでしょう。オリジンは、URL のプロトコル、ドメイン、ポートによって定義されます。 API が https://api..com:3001 のようなオリジンにあり、フロントエンドが https://.com にある場合、オリジンは異なると言われます。この状況では、両端のリソースにアクセスできるように CORS が必要になります。
サーバーに対してリクエストが行われると、ブラウザー (クライアント) とサーバーは HTTP ヘッダーを含むリクエストと応答を送信します。これらのヘッダーの中には、ブラウザーが通信をブロックしないようにするための追加のヘッダーが含まれています。
ブラウザが通信をブロックするのはなぜですか?
ブラウザのセキュリティ機能。リクエストがクライアントのオリジンとは異なるオリジンから送信されている場合、これが行われます。 CORS の結果として含まれる追加のヘッダーは、受信した応答を利用できることをクライアントに伝える方法です。

CORS に関する一般的な問題
Web 開発者は、複数のソースからの API を使用する Web アプリケーションを構築する場合など、さまざまなドメインのリソースにアクセスする必要があります。 CORS を実装すると、Web サーバーがリソースへのアクセスを許可する他のドメインを指定できるようになり、必要な Web アプリを構築できます。この動作はサーバー側で実装されるため、クライアント側で再構成することはできません。
CORS エラーが発生した場合は、必要なセキュリティ標準を満たしていないため、別のドメインからのリソースへのアクセス要求がサーバーによって拒否されたことを意味します。
これは、サーバーに適切な設定が行われていない場合に発生する可能性があります。しかし、心配しないでください。それを修正する簡単な方法があります。 Access-Control-Allow-Origin ヘッダーが正しく構成されていることを必ず確認してください。これにより、どのドメインがそのリソースへのアクセスを許可されるかがサーバーに通知されるため、サーバーが正しく設定されていない場合、問題が発生する可能性があります。

発生する可能性のあるその他の問題は次のとおりです。
- クロスオリジンリソース共有リクエストで 非単純な HTTP メソッド (DELETE や PUT など) を使用しようとしている場合は、サーバーがそれを許可していることを確認することが重要です。ブラウザではデフォルトで単純なメソッドのみが許可されるため、別のメソッドを使用する場合は、Access-Control-Allow-Methods ヘッダーを明示的に設定する必要があります。
- また、このようなリクエストを行うときは、サーバーが許可するブラウザからの認証情報 (Cookie や認証ヘッダーなど) の送信に注意する必要があります。
- さらに、単純でないリクエスト (カスタム ヘッダーを持つリクエストなど) の「プリフライト」照会によって、そのリクエストがサポートされていないことが判明した場合、サーバーは正しく応答しません。
- Web ページが別のドメインの画像、スクリプト、スタイルシートなどのリソース (コンテンツ配信ネットワーク上でホストされている) にアクセスしようとすると、リソースをホストしているサーバーが、ページがホストされているドメインからのリクエストを許可しない可能性があります。
幸いなことに、この問題を解決する方法がいくつかあります。解決策の 1 つは、適切なヘッダーを送信してクロスオリジン要求を許可するようにサーバーを構成することです。
もう 1 つのオプションは、プロキシ サーバーを使用して Web アプリケーションに代わってリクエストを行うか、JSON-P を使用してレスポンスをコールバック関数でラップすることです。
さらに、ヘッダーを処理し、問題なくリクエスト API を提供することで、クライアント側でのクロスオリジン リクエストを簡素化するライブラリもあります。
これらのさまざまな解決策を試すことで、これらの問題を回避し、Web アプリケーションが適切に機能するために必要なリソースに確実にアクセスできるようにすることができます。
注意 : これらの手法には独自のセキュリティ リスクがある可能性があるため、慎重に使用することが重要です。
CORS ヘッダー
応答ヘッダーまたは要求ヘッダーのいずれかであるセキュア ヘッダーの 1 つ。
応答ヘッダー
これらは、サーバーが応答で送り返すヘッダーです。
-
Access-Control-Allow-Origin: <origin>
: これは、サーバー上のリソースへのアクセスを許可されるオリジンを指定するために使用されます。特定のオリジンからのリクエストのみを許可する –Access-Control-Allow-Origin: https://.com
、またはオリジンが重要でない –Access-Control-Allow-Origin: *
を指定することが可能です。 -
Access-Control-Expose-Headers: <headers>
: 名前が示すように、これはブラウザーがアクセスできるヘッダーをリストします。 -
Access-Control-Max-Age: <seconds>
: これは、プリフライト リクエストの応答をキャッシュできる期間を示します。 -
Access-Control-Allow-Credentials: <boolean>
: これは、最初のリクエストが認証情報を使用して行われたときにブラウザが応答を利用できることを示します。 -
Access-Control-Allow-Methods: <methods>
: これは、リソースへのアクセスを試行するときに許可されるメソッドを示します。 -
Access-Control-Allow-Headers: <headers>
: これは、HTTP ヘッダーをリクエストで使用できることを示します。
以下は応答がどのようになるかの例です
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Vary: Access-Control-Request-Headers
Access-Control-Allow-Headers: Content-Type, Accept
Content-Length: 0
Date: Sat, 16 Nov 2019 11:41:08 GMT+1
Connection: keep-alive
リクエストヘッダー
CORS メカニズムを利用するためにクライアントのリクエストに含める必要があるヘッダーを次に示します。
-
Origin: <origin>
: これはクライアントのリクエストの発信元を示します。前に述べたように、フロントエンドとバックエンドを操作する場合、これがフロントエンド アプリケーションのホストになります。 -
Access-Control-Request-Method: <method>
: これは、リクエストの作成に使用される HTTP メソッドを示すためにプリフライト リクエストで使用されます。 -
Access-Control-Request-Headers: <header>
: これは、リクエストの作成に使用される HTTP ヘッダーを示すためにプリフライト リクエストで使用されます。
リクエストがどのようなものになるかの例を次に示します
curl -i -X OPTIONS localhost:3001/api \
-H 'Access-Control-Request-Method: GET' \
-H 'Access-Control-Request-Headers: Content-Type, Accept' \
-H 'Origin: http://localhost:3000'
プリフライトリクエスト
プリフライトリクエストについてあちこちで言及しましたが、これは一体何を意味するのでしょうか?
プリフライト リクエストは、クライアントがメイン リクエストの前にプリフライト リクエストを送信する必要がある場合に発生します。 プリフライト リクエストは、 サーバーがこれから行われるメイン リクエストをサポートしているかどうかを判断するための プローブ のようなものです。肯定的な確認が得られると、メインリクエストが送信されます。
リクエストがプリフライトリクエストではない場合、それは シンプルリクエスト と呼ばれます。
CORS の実装
ほとんどの場合、アプリケーションのバックエンドで設定を行うことになります。実装は、使用しているフレームワークによって異なります。このチュートリアルでは、NodeJS と Rails でそれを行う方法を見ていきます。
レール
rack-cors
gemを使用することをお勧めします。次に、これを
config/application.rb
ファイルに追加する必要があります。
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
expose: %i(access-token expiry token-type uid client),
methods: %i(get post put patch delete options head),
credentials: true
end
end
NodeJS
Node.js では次のようになります。
app.all(‘*’, (req, res, next) => {
res.header(‘Access-Control-Allow-Origin’, ‘*’);
res.header(‘Access-Control-Allow-Methods’, ‘PUT, GET, POST, DELETE, PATCH, OPTIONS HEAD’);
res.header(‘Access-Control-Allow-Headers’, ‘*’);
res.header(‘Access-Control-Allow-Credentials’, true);
next();
});
コード スニペットでは、サーバー上で利用可能なリソースへのアクセスを許可するオリジン、メソッド、ヘッダー、資格情報を設定しています。 Apache または Nginx で実装するには、このガイドを参照してください。
結論
CORS はポリシーを緩和して、ブラウザーが必要なリソースにアクセスできるようにします。これが何であるか、なぜ不可欠であるか、およびその設定方法を理解することは、Web アプリケーションを構築するときに直面する可能性のある問題を理解するのに役立ちます。