仲間の開発者と私は、過去数日間、アプリケーションで奇妙な問題を経験していました。具体的には、彼はAPIを作成しており、私はWebフロントエンドを作成しています。 UIは別のポートから実行されるため、UIがAPIにリクエストを送信できるように、アプリケーションでCORSをセットアップする必要があります。
詳細については触れませんが、これはCORSに深く関与する必要があった最初のプロジェクトです。具体的には、問題は、JSONデータをリクエスト本文として送信し、ヘッダーに_application/json
_のコンテンツタイプを指定するUIコードに関連していました。これはCORS内で許容されるコンテンツタイプではないため、プリフライトはリクエストを拒否しました。
当時、私たちのどちらもプリフライトリクエストを認識していなかったため、fetch(...)
呼び出しがヘッダーを変更し、データをドロップすると想定していました。最終的にCORSのメカニズムを詳しく調べたところ、プリフライトリクエストが私のコンテンツタイプが受け入れられなかったという応答を受け取ったことに問題があることがわかりました。
問題を修正した後、プリフライトチェックの目的は何なのだろうと思わずにはいられませんでした。具体的には、これはブラウザー/ UIにはメリットがありません。 CORSで受け入れられない要求を行うとエラーが発生し、サーバーからの応答により、要求が不要な理由の詳細が伝えられる可能性があります。つまり、プリフライトチェックをスキップし、サーバーからの応答に依存してリクエストが正しいかどうかを指示できます。これにより、ブラウザーが1回の呼び出しで2つのリクエストを行う必要がなくなります。
プリフライトチェックもサーバーに利益をもたらしません。サーバーすべきプリフライト呼び出しが行われたかどうかに関係なく、CORS要件に一致しない要求はすべて拒否されます。
では、プリフライトのポイントは何ですか?デフォルトの許容CORSヘッダープロパティがクライアントによって要求されているものと異なる場合、ブラウザーが1つではなく呼び出しを行うことが適切なのはなぜですか?
つまり、プリフライトチェックをスキップして、サーバーからの応答に依存してリクエストが正しいかどうかを指示できます。これにより、ブラウザーが1回の呼び出しで2つのリクエストを行う必要がなくなります。
これは、サーバーが最初にリクエストを適切に検証していることを前提としています。問題は、多くのサーバーが動作しないことです。これがCSRFが機能する理由です。
従来、JavaScriptを使用してクロスサイトリクエストを実行することは不可能でした。 CORSでは、この制限を緩和できます。ただし、CORSは、誤ってセキュリティを低下させないように設計されています。 XHRがクロスサイトで実行できないという事実に単純に依存するサーバー側コードは、誤って安全になることはありません。 JavaScriptで実行される単純なクロスサイトリクエスト以外のすべての理由により、ブラウザは最初に、サーバーが実際のリクエストを実行する前にプリフライトリクエストを送信してクロスサイトリクエストを明示的に許可することを確認します。