web-dev-qa-db-ja.com

jqueryの.ajax()メソッドがセッションCookieを送信しないのはなぜですか?

$.ajax()経由でサイトにログインした後、そのサイトに2回目の$.ajax()リクエストを送信しようとしています - ただし、FireBugを使用して送信されたヘッダーを確認すると、リクエストにセッションクッキーは含まれません。

何がおかしいのですか?

315
user345625

AJAX呼び出しは、呼び出し元のURLが呼び出し元のスクリプトと同じドメインにある場合にのみCookieを送信します。

これはクロスドメイン問題かもしれません。

呼び出しスクリプトがwww.domain-a.com上にあるときにwww.domain-b.comからURLを呼び出そうとした可能性があります(つまり、クロスドメイン呼び出しを行った場合、ブラウザはプライバシーを保護するためにCookieを送信しません)。

この場合、あなたのオプションは以下のとおりです。

  • ドメインbに常駐し、リクエストをドメインaに転送する小さなプロキシを作成します。プロキシは呼び出し元のスクリプトと同じサーバー上にあるため、ご使用のブラウザでプロキシを呼び出すことができます。
    このプロキシは、ドメイン名aに送信できるCookie名と値のパラメータを受け入れるように設定できます。しかしこれが機能するためには、ドメインA上のサーバーが認証を希望するCookieの名前と値を知っている必要があります。
  • JSONオブジェクトを取得している場合は、代わりに JSONP リクエストを使用してください。 jQueryはこれらをサポートしています。しかし、あなたはdomain-aであなたのサービスを変更して、それが有効なJSONP応答を返すようにする必要があります。

それが少しでも助けになればうれしいです。

203
flu

クロスドメインシナリオで運用しています。ログイン中、リモートサーバーはAccess-Control-Allow-Credentialsをtrueに設定してSet-Cookieヘッダーを返しています。

次のリモートサーバーへのAjax呼び出しはこのクッキーを使うべきです。

CORSのAccess-Control-Allow-Credentialsはクロスドメインロギングを可能にするためにあります。例として https://developer.mozilla.org/En/HTTP_access_control をチェックしてください。

私にとっては、それはJQueryのバグのようです(または少なくとも次のバージョンで提供される機能)。

更新:

  1. クッキーはAJAX responseから自動的に設定されません(引用: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login -experience /

    どうして?

  2. 手動で設定するためにレスポンスからクッキーの値を取得することはできません( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader

    よくわかりません..

    jquery.ajax()XMLHttpRequest.withCredentials = "true"パラメータの設定を依頼する方法があるはずです。

答え:あなたは http://api.jquery.com/jQuery.ajax/xhrFieldsパラメータを使うべきです

ドキュメントの例は次のとおりです。

$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

サーバーがこの要求に正しく応答することも重要です。 @Frédéricと@Pebblから素晴らしいコメントをここにコピーしてください。

Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *

だから要求があるとき:

Origin: http://foo.example
Cookie: pageAccess=2

サーバーは次のように応答します。

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true

[payload]

そうでなければペイロードはスクリプトに返されません。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials を参照してください。

360
Kangur

を使う

xhrFields: { withCredentials:true }

私のjQueryのAjax呼び出しの一部としてソリューションの一部にすぎませんでした。私のリソースからのOPTIONSレスポンスで返されるヘッダーも必要です。

Access-Control-Allow-Origin : http://www.wombling.com
Access-Control-Allow-Credentials : true

OPTIONS呼び出しの応答ヘッダーには "Origin"が含まれ、oneallowednot"だけが重要でした。 * "私はリクエストからOriginを読み、それをレスポンスに投入することでこれを達成しました - おそらく制限の元々の理由を回避するでしょう、しかし私のユースケースではセキュリティは最優先事項ではありません。

W3C規格ではスペースで区切られたリストが許可されていますが、Chromeでは許可されていません。 http://www.w3.org/TR/cors/#access-control-allow-Origin-response-header NB「実際には」ビット。

これをinit関数に入れてください。

$.ajaxSetup({
  xhrFields: {
    withCredentials: true
  }
});

それが動作します。

39
Alex Athlan

この質問に対する良い回答はすでにたくさんありますが、Cookieドメインが一致するためにセッションCookieが送信されることが予想される場合を明確にすることが役立つ場合がありますが、AJAX要求は別のサブドメインに対して行われています。この場合、*。mydomain.comドメインに割り当てられたCookieがあり、それをAJAXリクエストに含めることを望んでいます。 todifferent.mydomain.com "。デフォルトでは、Cookieは送信されません。この問題を解決するためにセッションCookieでHTTPONLYを無効にする必要はありません。ウォンブルが提案したこと( https://stackoverflow.com/a/23660618/545223 )を実行して、次の操作を行います。

1)ajaxリクエストに以下を追加してください。

xhrFields: { withCredentials:true }

2)異なるサブドメインのリソースのレスポンスヘッダーに以下を追加します。

Access-Control-Allow-Origin : http://original.mydomain.com
Access-Control-Allow-Credentials : true
11
munchbit

他の解決策を試してもまだうまくいかない場合は、私の場合に問題が何であるかを見つけました。 contentTypeを "application/json"から "text/plain"に変更しました。

$.ajax(fullUrl, {
    type: "GET",
    contentType: "text/plain",
    xhrFields: {
         withCredentials: true
    },
    crossDomain: true
});
5
Janno Teelem

私はこれと同じ問題を抱えていて、私のスクリプトが単にsessionidクッキーを取得していないことを確認していました。

私は私のフレームワーク(Django)がデフォルトとしてHttpOnlyでsessionidクッキーを渡していたことをブラウザでsessionidクッキー値を見ることによって考え出しました。これは、スクリプトがsessionid値にアクセスできないため、リクエストと一緒に渡されないことを意味します。非常に多くのものがアクセス制限を必要とするAjaxを使用するとき、HttpOnlyがデフォルト値になることをばかげているような種類のもの。

これを修正するために設定を変更しました(SESSION_COOKIE_HTTPONLY = False)が、他の場合にはクッキーパスの "HttpOnly"フラグになるかもしれません。

3
wiwa

上記の回答に記載されている手順に加えて、localhostまたはlocalhost上のポート(localhost:8080など)で開発している場合は、Set-Cookieヘッダーにドメイン値を渡さないようにする必要もあります。
Set-Cookieヘッダーでドメインをlocalhostに設定することはできません - これは正しくありません - ドメインを省略するだけです。

明示的なドメインを持つlocalhostのクッキー および を参照してください。なぜasp.netはlocalhostにクッキーを作成しないのですか?

0
jitin

Localhostとdev環境の両方でPHPSESSID cookieの問題を設定することについての私の2セントだけ。私はAJAXをローカルホスト上のREST AP​​Iエンドポイントに呼び出します。そのアドレスがmysite.localhost/api/member/login/(私の開発環境ではvirtal Host)であるとしましょう。

  • このリクエストを Postman で実行すると、問題は解決せず、レスポンスにPHPSESSIDが設定されます。

  • BrowsersyncプロキシページからAJAXを介してこのエンドポイントをリクエストすると(たとえば、ブラウザのアドレス行の122.133.1.110:3000/test/api/login.phpから、ドメインがvs vsmysite.localhostと異なるため)、PHPSESSIDがcookieの中に表示されません。

  • 私が同じドメイン(すなわちmysite.localhost/test/api/login.php)上のページから直接このリクエストをするとき、PHPSESSIDはまさしくうまく設定されます。

そのため、これは上記の@flu 回答で述べられているように、クロスオリジンオリジンリクエストクッキーの問題です

0
bob-12345