386 Stimmen

Warum sendet die .ajax()-Methode von jQuery mein Session-Cookie nicht?

Nach der Anmeldung über $.ajax() zu einer Website, ich versuche, eine zweite $.ajax() Aber wenn ich die mit FireBug gesendeten Header überprüfe, ist kein Sitzungscookie in der Anfrage enthalten.

Was mache ich falsch?

442voto

Kangur Punkte 7447

Ich bin in einem bereichsübergreifenden Szenario tätig. Während der Anmeldung gibt der Remote-Server den Set-Cookie-Header zusammen mit Access-Control-Allow-Credentials auf true gesetzt.

Der nächste Ajax-Aufruf an den Remote-Server sollte dieses Cookie verwenden.

CORS's Access-Control-Allow-Credentials ist dazu da, eine domänenübergreifende Protokollierung zu ermöglichen. Prüfen Sie https://developer.mozilla.org/En/HTTP_access_control für Beispiele.

Für mich scheint es wie ein Fehler in JQuery (oder zumindest Feature-to-be in der nächsten Version).

UPDATE:

  1. Cookies werden nicht automatisch von der AJAX-Antwort gesetzt (Zitat: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ )

    Warum?

  2. Sie können den Wert des Cookies nicht aus der Antwort abrufen, um ihn manuell zu setzen ( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader )

    Ich bin verwirrt

    Es sollte eine Möglichkeit geben, zu fragen jquery.ajax() zum Einstellen XMLHttpRequest.withCredentials = "true" Parameter.

ANTWORT: Sie sollten Folgendes verwenden xhrFields Nennwert von http://api.jquery.com/jQuery.ajax/

Das Beispiel in der Dokumentation lautet:

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

Wichtig ist auch, dass der Server auf diese Anfrage richtig antwortet. Ich kopiere hier die tollen Kommentare von @Frédéric und @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: *

Wenn die Anfrage also lautet:

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

Der Server sollte mit antworten:

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

[payload]

Andernfalls wird die Nutzlast nicht an das Skript zurückgegeben. Siehe: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

241voto

flu Punkte 13677

AJAX-Aufrufe senden nur dann Cookies, wenn sich die aufgerufene URL auf derselben Domain befindet wie das aufrufende Skript.

Dies kann ein bereichsübergreifendes Problem sein.

Vielleicht haben Sie versucht, eine Url von www.domain-a.com während Ihr aufrufendes Skript auf www.domain-b.com (Mit anderen Worten: Sie haben einen Cross-Domain-Call gemacht. In diesem Fall sendet der Browser keine Cookies, um Ihre Privatsphäre zu schützen).

In diesem Fall haben Sie folgende Möglichkeiten:

  • Schreiben Sie einen kleinen Proxy, der auf Domain-b residiert und Ihre Anfragen an Domain-a weiterleitet. Ihr Browser wird Ihnen erlauben, den Proxy aufzurufen, da er sich auf demselben Server befindet wie das aufrufende Skript.
    Dieser Proxy kann dann von Ihnen so konfiguriert werden, dass er einen Cookie-Namen und einen Wert-Parameter akzeptiert, den er an Domain-a senden kann. Damit dies funktioniert, müssen Sie jedoch den Namen und den Wert des Cookies kennen, den Ihr Server in Domäne A zur Authentifizierung benötigt.
  • Wenn Sie JSON-Objekte abrufen, versuchen Sie, eine JSONP Anfrage. jQuery unterstützt diese. Sie müssen jedoch Ihren Dienst auf Domain-a so ändern, dass er gültige JSONP-Antworten zurückgibt.

Ich bin froh, wenn das auch nur ein bisschen geholfen hat.

51voto

Verwendung von

xhrFields: { withCredentials:true }

als Teil meines jQuery-Ajax-Aufrufs war nur ein Teil der Lösung. Ich brauchte auch, um die Header in der OPTIONS-Antwort von meiner Ressource zurückgegeben haben:

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

Es war wichtig, dass nur eine zulässige "Herkunft" im Antwort-Header des OPTIONS-Aufrufs stand und no "*". Ich habe dies erreicht, indem ich den Ursprung aus der Anfrage gelesen und in die Antwort eingefügt habe. Damit habe ich wahrscheinlich den ursprünglichen Grund für die Einschränkung umgangen, aber in meinem Anwendungsfall ist die Sicherheit nicht vorrangig.

Ich hielt es für sinnvoll, ausdrücklich zu erwähnen, dass es nur einen Ursprung geben darf, da der W3C-Standard eine durch Leerzeichen getrennte Liste zulässt, Chrome aber nicht! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header Beachten Sie den Teil "in der Praxis".

45voto

Alex Athlan Punkte 449

Fügen Sie dies in Ihre init-Funktion ein:

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

Es wird funktionieren.

16voto

munchbit Punkte 531

Es gibt bereits viele gute Antworten auf diese Frage, aber ich dachte, es könnte hilfreich sein, den Fall zu klären, in dem man erwarten würde, dass das Sitzungscookie gesendet wird, weil die Cookie-Domäne übereinstimmt, aber es wird nicht gesendet, weil die AJAX-Anfrage an eine andere Subdomäne gestellt wird. In diesem Fall habe ich ein Cookie, das der *.meinedomain.de Domain, und ich möchte, dass sie in eine AJAX-Anfrage an anders.meinedomain.de ". Standardmäßig wird das Cookie nicht gesendet. Sie brauchen HTTPONLY für das Sitzungscookie nicht zu deaktivieren, um dieses Problem zu lösen. Sie müssen nur das tun, was wombling vorgeschlagen hat ( https://stackoverflow.com/a/23660618/545223 ) und gehen Sie wie folgt vor.

1) Fügen Sie Ihrer Ajax-Anfrage Folgendes hinzu.

xhrFields: { withCredentials:true }

2) Fügen Sie Folgendes zu Ihren Antwort-Headern für Ressourcen in der anderen Subdomain hinzu.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X