プリフライトリクエストとは何か?CORS チェックの解説
Scrapeless Agent Browser は、対象ページがブラウザのクロスオリジンリクエスト規則の対象であり続ける、ブラウザベースのワークフローを実行します。
要約
- CORS プリフライトは、提案されたクロスオリジンリクエストの許可を確認します。 ブラウザは、特定のアプリケーションリクエストの前に OPTIONS リクエストを送信します。
- 成功した OPTIONS ステータスだけでは不十分です。 ブラウザは、要求される CORS フィールドを提案された操作と照合して検証する必要があります。
- CORS の許可は API 認可の代わりにはなりません。 リソースサーバーは依然として資格情報と操作権限をチェックします。
- コマンドラインでの成功はブラウザでのアクセスを証明しません。 ブラウザのオリジンポリシーは、サーバー側 HTTP クライアントが強制しない追加チェックを行います。
プリフライトは提案されたブラウザリクエストについて問い合わせる
CORS プリフライトは、ブラウザがサーバーに対して、特定のクロスオリジンリクエストを許可しているかどうかを確認するために送信する HTTP OPTIONS リクエストです。これは呼び出し元オリジン、意図されたメソッド、および関連するリクエストフィールド名を記述します。サーバーのレスポンスがブラウザのチェックを満たせば、ブラウザはアプリケーションリクエストを続行できます。プリフライトはブラウザのアクセスモデルにおける許可のネゴシエーションであり、アプリケーション操作そのものではありません。
この動作は Fetch Standard の CORS モデル によって定義されています。オリジンはスキーム、ホスト、ポートによって決定されるため、ドメインが非常によく似て見えていても、2 つの URL が別のオリジンに属することがあります。あるオリジンから配信されるフロントエンドと別のオリジンから配信される API が、ブラウザの JavaScript から API レスポンスへアクセスするために CORS 設定を必要とする場合があります。
CORS は Cross-Origin Resource Sharing の略です。これは、同一オリジンセキュリティモデルの中で、サーバーが特定のクロスオリジンブラウザ相互作用を許可するためにオプトインできるようにするものです。このポリシーはブラウザによって強制され、サーバーはレスポンスフィールドを通じて許可内容を宣言します。アプリケーションは、自身の送信リクエストにレスポンス用の許可フィールドを追加することで、拒否されたクロスオリジンリクエストを解決することはできません。
すべてのクロスオリジンリクエストがプリフライトされるわけではない
一部のクロスオリジンリクエストは、CORS で safelisted とされるメソッドおよびフィールドの規則の範囲内に収まり、プリフライトを必要としません。正確な条件にはメソッド、リクエストフィールド値、および関連する Fetch の挙動が含まれます。非 safelisted フィールドを伴う GET リクエストはプリフライトを必要とする場合がありますが、適切に制約された POST はそれを回避できる場合があります。したがってメソッド名だけでは判断規則として不完全です。
一般的なトリガーには、safelisted セット外のメソッド、Authorization フィールド、および safelisted なメディアタイプに含まれない JSON の Content-Type があります。これらの例は多くのブラウザのネットワークトレースを説明しますが、完全な判定は Fetch の規則に属します。すべての GET を simple と表現したり、すべての POST がプリフライトされると表現したりすることは避けてください。実際のリクエスト構成を確認しましょう。
この ブラウザのプリフライトリクエストの説明 は、事前の OPTIONS リクエストと実際のリクエストを区別します。サーバーはプリフライトを必要としないリクエストを受け取ることができますが、そのレスポンスをブラウザが JavaScript に公開することを依然として拒否する場合があります。したがって CORS は、あらゆるクロスオリジンリクエストがサーバーに到達するのを防ぐ万能の障壁として説明すべきではありません。
ブラウザは意図されたメソッドとフィールドを記述する
プリフライトには、呼び出し元オリジンを識別するための Origin が含まれます。Access-Control-Request-Method は、実際のリクエストにブラウザが使用しようとしているメソッド名を示します。Access-Control-Request-Headers は、許可が必要な関連リクエストフィールド名を列挙します。これらは提案された操作の記述であり、OPTIONS リクエスト自体がその操作を実行したり、アプリケーションの完全なペイロードを運んだりすることを意味するものではありません。
サーバーは、該当する場合、許可されたオリジン、メソッド、およびリクエストフィールドを記述するフィールドで応答します。ブラウザはそれらの宣言を提案されたリクエストと照合して評価します。必要な許可を省略したり、異なるメソッドを許可したりする汎用的な成功 OPTIONS ハンドラーでは不十分です。どのポリシー部分が失敗したのかを診断できるよう、比較を正確に保ちましょう。
| フィールド | 方向 | やり取りにおける意味 |
|---|---|---|
| Origin | ブラウザリクエスト | 呼び出し元ページのオリジン |
| Access-Control-Request-Method | プリフライトリクエスト | アプリケーションリクエストに提案されるメソッド |
| Access-Control-Request-Headers | プリフライトリクエスト | 許可が必要なリクエストフィールド名 |
| Access-Control-Allow-Origin | サーバーレスポンス | サーバーが許可するオリジンアクセス |
| Access-Control-Allow-Methods | プリフライトレスポンス | 許可されるリクエストメソッド |
| Access-Control-Allow-Headers | プリフライトレスポンス | 許可されるリクエストフィールド名 |
| Access-Control-Max-Age | プリフライトレスポンス | プリフライト結果をキャッシュすることが許可される有効期間 |
アプリケーションリクエストは、別個の通信として扱われます。到達すると、API はその認証情報、パラメータ、権限を検証します。そのレスポンスにも、ブラウザからアクセスするために必要な CORS フィールドが含まれている必要があります。事前チェックに合格しても、その後の不正な、または不正形式のアプリケーション操作が成功するわけではなく、実際のレスポンスがオリジンポリシーの処理から免除されることもありません。
認証情報によりオリジン設定はより限定的になる
認証付きブラウザリクエストでは、CORS レスポンスポリシーが認証モードおよび要求元オリジンと整合している必要があります。認証付きレスポンスを公開する場合、許可オリジンにワイルドカードを使って明示的なオリジンの一般的な代替とすることはできません。サーバーには、適切な認証情報の許可も必要です。これらのフィールドは、検査せずに任意の入力を反映させるのではなく、管理されたオリジンポリシーから構成してください。
Cookie は CORS を超える追加のルールを導入します。あるリクエストは CORS ポリシーを満たしていても、Cookie の配信は Cookie 属性やブラウザのプライバシー動作によって制約される場合があります。逆に、Cookie が存在していても、サーバーがそのセッションを受け入れたことにはなりません。Cookie の配信、CORS の公開、およびアプリケーションの認可は、個別の診断対象として扱ってください。
The CORS における認証情報とレスポンスフィールドのガイダンス は、これらの相互作用を扱います。標準モデルでは、たとえ提案されたアプリケーションリクエストが認証付きであっても、プリフライトには通常認証情報は含まれません。すべての OPTIONS リクエストにログイン済みセッションを要求するミドルウェアは、そのため、認可されたアプリケーションリクエストが評価される前にネゴシエーションを遮断してしまう可能性があります。
失敗したプリフライトと失敗した API 呼び出しは別物
失敗したプリフライトは、ブラウザが提案されたアプリケーションリクエストを送信するのを止めることがあります。その場合、ゲートウェイは OPTIONS を記録していても、API ルートのログに対応するアプリケーション操作が存在しないことがあります。どの通信が発生したのかを特定することから診断を始めてください。コンソールの一般的な CORS エラーだけでは、ルーティング、フィールドポリシー、認証情報、あるいは実際のレスポンスのどれが問題を引き起こしたのかは特定できません。
アプリケーションリクエストがサーバーに到達していた場合は、そのステータスと固有の CORS レスポンスフィールドを調査してください。サービスは、有益なエラーボディを返していても、エラーレスポンスにオリジン許可が抜けているためにブラウザの JavaScript がそれを読めないことがあります。通常の API 認可を維持しながら、成功レスポンスとエラーレスポンスの両方に、意図した CORS ポリシーを一貫して適用してください。あらゆる失敗をオリジン許可リストの変更に結び付けないでください。
OPTIONS リクエストが常に CORS プリフライトであるとは限りません。HTTP では OPTIONS は、より一般的にターゲットリソースの通信オプションについて問い合わせるリクエストとして定義されています。 HTTP OPTIONS のセマンティクス および CORS リクエストフィールドの有無によって、ブラウザのプリフライトと、手動で発行された OPTIONS リクエスト、あるいはその他のインフラストラクチャチェックを区別することができます。メソッド名だけでなく、実際に存在するリクエストを診断してください。
プリフライトキャッシュには独自のライフサイクルがある
ブラウザは、Access-Control-Max-Age や実装上の制限など、適用されるルールに従って、成功したプリフライト許可をキャッシュできます。このキャッシュは、通常のアプリケーションレスポンスコンテンツのキャッシュとは別物です。そのため、後続のリクエストが新たな OPTIONS 通信なしで現れる理由を説明できます。あるトレースにプリフライトが存在しないからといって、そのリクエストにプリフライトが決して要求されないことを意味しません。
キャッシュのスコープは、リクエストコンテキスト、オリジン、ターゲット、メソッド、およびフィールドの許可にも依存します。あるルートやフィールド集合に対する成功したチェックが、ホスト上のあらゆる操作に対する包括的な承認になるわけではありません。デバッグ時には、提案されたメソッドとリクエストフィールドをターゲット URL とともに記録してください。これらの詳細を欠いたトレース同士を比較すると、正常なポリシーの違いが一貫性のない挙動のように見えてしまうことがあります。
異なる呼び出し元に対して異なるオリジン許可を返すサーバーは、中間キャッシュの挙動を考慮する必要があります。 HTTP キャッシュ選択ルール は、レスポンスの差異を不適切な再利用から守るためにどのように表現しなければならないかを説明しています。アプリケーションレスポンスが Origin によって変化する場合は、ある呼び出し元のオリジン宣言が別の呼び出し元に無差別に再利用されないよう、関連するキャッシュのバリエーションを構成してください。
オリジンからアプリケーションまでの通信をデバッグする
呼び出し元ページの完全なオリジンと最終的な API ターゲットから始めてください。リダイレクトやゲートウェイが OPTIONS をアプリケーションメソッドとは異なる経路にルーティングしていないか確認します。提案されたメソッドとフィールドをサーバーの明示的なポリシーと比較してください。そのうえで、実際のリクエストが到達したかどうか、またそのレスポンスに期待する CORS フィールドが含まれているかどうかを調査します。この手順により、ポリシーを無差別に弱めることなく、失敗箇所を特定できます。
コマンドラインクライアントは HTTP レスポンスの調査には役立ちますが、それ自体ではブラウザの CORS 強制を再現しません。バックエンドプロセスからのリクエストが成功したとしても、それは単にそのプロセスが自分自身のネットワークおよび認証コンテキストのもとでレスポンスを取得できたことを示すだけです。ブラウザは依然としてオリジンルールを評価します。レスポンスを隠すモードにクライアントを変更しても、保護されたレスポンスコンテンツを読む許可が生じるわけではありません。
診断情報はサニタイズされた状態に保ってください。認可トークンや Cookie を共有トレースに貼り付けてはいけません。通常、フィールド名、オリジン、ルート、メソッド、ステータス、および許可フィールドの値だけで、CORS の不一致を説明するには十分です。アプリケーションが個人情報レコードに触れる場合は、認可された調査に必要な最小限の内容だけを取得し、その取得を適切なアクセス境界の中にとどめてください。
ブラウザ自動化でもオリジンモデルは依然として適用される
Scrapeless Agent Browser は、自動ナビゲーションとインタラクションのためのブラウザ環境を提供しますが、ターゲットページのクロスオリジンアプリケーション契約を変更するものではありません。 Agent Browser の概要 ブラウザーの機能を説明するものであり、ページと API の所有者は依然としてオリジンポリシーと呼び出し元に付与される権限に対して責任を負います。ブラウザー制御用の接続を、対象ページ内で実行される JavaScript から分離してください。クラウドブラウザーに接続するオートメーションクライアントと、クロスオリジン API に到達するページスクリプトは、異なるネットワーク相互作用です。制御チャネルで成功しても、そのページの API 呼び出しが CORS を通過したことは証明できません。ページが何にアクセスできたかを説明する際には、対象リクエストとそれに対応するレスポンスを観察してください。
The Fetch リクエストのワークフロー は HTTP クライアントに関連する資料であり、 Scrapeless pricing はブラウザーサービスの利用料金について説明しています。認可されたテストでは、期待されるオリジン、操作、および目に見えるページ結果を定義してください。合格と見なすブラウザー観察結果は、OPTIONS ステータスで止めるのではなく、ポリシーのやり取りとその結果としてのアプリケーション動作の両方を確認すべきです。
結論
プレフライトは、特定の提案されたクロスオリジン操作を、一定のブラウザーリクエストが進行する前に評価します。呼び出し元オリジン、メソッド、フィールド名、認証情報モード、そして 2 つのレスポンスを検査してください。ブラウザーの権限チェックと API 認可を分離し、失敗したやり取りを所有するコンポーネント側でポリシーを診断してください。
Web データワークフローを構築する
Agent Browser を使用して許可されたページワークフローを観察し、実際の対象リクエスト境界でクロスオリジン動作を検証してください。
今すぐ登録して $5 in free credit — クレジットカード不要.
$5 分のクレジットを獲得 →FAQ
すべてのクロスオリジンリクエストにプレフライトが必要ですか?
すべてのクロスオリジンリクエストにプレフライトが必要なわけではありません。ブラウザーはメソッド、リクエストフィールド、その値、および適用される Fetch の規則を評価します。プレフライトなしのリクエストであっても、JavaScript がそのクロスオリジンレスポンスにアクセスするには、適切な CORS レスポンス許可が必要です。
OPTIONS の HTTP 200 は CORS が正しいことを証明しますか?
OPTIONS への HTTP 200 は CORS が正しいことを証明しません。ブラウザーは許可されたオリジン、メソッド、フィールド、認証情報要件も確認します。実際のアプリケーションレスポンスは、事前のやり取りが成功した後でも、独自の CORS チェックを満たさなければなりません。
CORS は認証システムですか?
CORS は認証システムではありません。ブラウザーコードによるクロスオリジンアクセスを制御するものです。API は、ブラウザーのオリジンポリシーチェックを実装していないクライアントも含めて、認証情報を個別に検証し、リソース権限を強制する必要があります。
なぜバックエンドからは動く API がブラウザーでは失敗するのですか?
API はバックエンドからは動作しても、ブラウザーでは失敗することがあります。これはブラウザーの JavaScript が same-origin 規則と CORS 規則を満たさなければならないためです。また、認証情報、最終的な URL、リクエストフィールドを比較してください。2 つのクライアントが同等のリクエストを送信していない可能性があります。
なぜ後のネットワークトレースでは OPTIONS リクエストが存在しないのですか?
後のトレースに OPTIONS が含まれないのは、そのリクエストにプレフライトが不要であるか、有効なプレフライト許可が既にキャッシュされているためです。結論を出す前に、リクエストの完全なコンテキストを比較してください。アプリケーションレスポンスのキャッシュとプレフライト許可のキャッシュは、異なるメカニズムです。