クロスドメイン時の Cookie をどのように扱うか?

序文

リクエストの送信から返信までには、ブラウザとサーバーの連携が必要です。ブラウザは独自のリクエスト パラメータをサーバーに送信する必要があります。サーバーはパラメータを検証した後、データを返すだけでなく、リクエストがキャッシュされているかどうか、Cookie やその他の情報もブラウザに通知することがあります。リクエストがクロスオリジンリクエストの場合、プロセスはさらに複雑になります。次に、ドメインをまたいでどのような問題が発生するのか、フロントエンドとバックエンドでどのような連携が必要になるのかを見ていきましょう。

共通ドメイン

私にはシャオ・ワンという名前の友達がいます。フロントエンドの Xiao Wang とバックエンドの同僚 Xiao Ma は、ログイン API を共同でデバッグする予定です。/login であるとします。Xiao Wang は、ログイン アカウントとパスワードを準備した後、喜んで投稿の送信を開始しました。結果は予期せぬもので、リクエストへの応答がブラウザによってインターセプトされ、ブラウザは慎重にコンソールにエラーをスローしました。
プレビュー
Xiao Wang が翻訳したところ、CORS 戦略によってブロックされていたことが判明しました。この戦略は、サーバーが異なるオリジンからのリクエストを許可する場合、返される応答ヘッダーに Access-Control-Allow-Origin ヘッダーを含める必要があることを大まかに意味します。それ以外の場合、ブラウザーが応答を取得し、応答ヘッダーにそのようなヘッダーが存在しないことが判明すると、さらなる処理のために応答を js に渡す代わりに、応答を飲み込みます。

Xiao Wang は Xiao Ma にこのことを伝え、Xiao Ma は返されたヘッダーに追加しました

Access-Control-Allow-Origin: *

これで、Xiao Wang は最終的に返された結果を取得できるようになりました。

ここで注意すべき点は、ブラウザはリクエストの段階でリクエストをインターセプトするのではなく、通常通りリクエストを送信し、サーバーからのレスポンスを取得した後、ヘッダーに Access-Control-Allow-Origin ヘッダーがあるかどうかの確認を開始します。応答ヘッダー。そうでない場合は応答します。結果は js に送信されません。

クロスドメインの単純でないリクエスト

その後、Xiao Wang さんは、投稿で本文をフォーム形式で送信するのは面倒だと感じ、リクエスト本文を JSON 形式で送信したいと考えました。Xiao Ma さんは、それはほんの数行のコードだと感じたので、同意しました。しかし、Xiao Wang がメッセージ本文を JSON に変更した後、メッセージ本文が再び CORS によってインターセプトされ、次のエラーがスローされたことがわかりました。
プレビュー

上記のエラー レポートには、プリフライトという単語がありました。それで、ここで何が起こっているのでしょうか?リクエスト本文を変更した後、このクロスドメインリクエストは単純なリクエストではなくなり、リクエストが開始される前にプリフライトリクエストを作成する必要があることがわかりました。では、簡単なリクエストとは何でしょうか?

  • リクエストメソッドにはGET、HEAD、POSTが含まれます
  • 応答ヘッダーには、CORS セキュリティ ヘッダー以外のヘッダーを含めることはできません。
  • Content-Type は text/plain、multipart/form-data、application/x-www-form-urlencoded に限定されます

json データのコンテンツ タイプにより、このポスト リクエストは単純なリクエストではなくなりました。また、単純でないリクエストについては、以前はすべてのドメイン名のクロスドメイン アクセスが禁止されていました。
したがって、Access Control-Allow-Origin を特定の要求ドメイン名に変更する必要があります。開発モードでは、http://localhost:3000 などになります。

Xiao Ma は Access-Control-Allow-Origin を再変更しており、Xiao Wang は再びログイン成功の結果を取得します。次の API を共同でデバッグできます。

Cookie を使用したクロスドメイン

ログインはセッションに基づいています。つまり、ログインが成功すると、サーバーは set-cookie を通じてブラウザに Cookie を設定します。これにより、次回同じソースで API にアクセスしたときに、Cookie が設定されます。連れて来られる。

しかし、奇妙なことに、Xiao Wang は、ログインに成功した後、別のインターフェイスを呼び出したが、Cookie が送信されなかったことに気づきました。そのため、サーバーはユーザー情報を認識できず、最終的にエラー (ステータス コード 401) を返しました。 )。

認証情報あり

ブラウザがクロスドメイン リクエストを開始するとき、ブラウザは率先して Cookie を取得しないことが判明しました。リクエストに Cookie が必要な場合、開発者はオプションを設定する必要があります。フェッチ API を例に挙げます。

fetch('http://baidu.com:3000', {
    
    
    // ...
	credentials: 'include'
})

xhr API を使用してリクエストする場合は、次のように記述する必要があります。

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';

function callOtherDomain(){
    
    
  if(invocation) {
    
    
    invocation.open('GET', url, true);
    invocation.withCredentials = true; // 带上cookie
    invocation.onreadystatechange = handler;
    invocation.send();
  }
}

Xiao Wang はリクエストを設定した後、別のリクエストを行いました。しかし、クッキーがまだ取り上げられていないことがわかりました。Xiao Wang さんは、仕方なく MDN 上の情報を確認し続けたところ、cookie を設定するときに SameSite 属性を含める必要があることがわかりました。

同じサイト

SameSite は csrf 攻撃を防ぐために生成される属性です。CSRF 攻撃が何なのかわからない場合は、まず自分で確認してください。

リクエストに Cookie を含める必要があるため、set-cookie のときに Cookie の SameSite を none に設定する必要があり、sameSite を none に設定するときに Secure も設定する必要があるため、リクエストは https に基づく必要があります。 ;

最後に Xiao Wang が Xiao Ma に API の異議申し立てと変更を依頼したとき、サーバーは最終的にリクエストの送信者を認識し、正しい結果を返しました。

要約する

多くの場合、私たちはリクエストの本文が何であるか、レスポンスが正しく返されるかどうかだけに注意を払い、ヘッダー部分を無視することがあります。誰もが知っているように、この記事の一連の Access-Control-Allow-* ヘッダーなど、ヘッダーはキャッシュ、Web セキュリティ、ブラウザーによる正しい解析結果において重要な役割を果たします。

Web の安全性を高めるために、CORS は常に更新されており、たとえば、この提案では、パブリック ネットワークまたはプライベート ネットワークからローカル ネットワークにアクセスする場合、クロスドメイン ヘッダーである Access-Control-Allow-Private を使用することを規定しています。・ネットワークの設定が必要です。

おすすめ

転載: blog.csdn.net/hyqhyqhyqq/article/details/130618876