360 votes

Pourquoi la méthode .ajax () de jquery n'envoie pas mon cookie de session?

Après m'être connecté via $.ajax() à un site, j'essaye d'envoyer une seconde requête $.ajax() à ce site - mais quand je vérifie les en-têtes envoyés avec FireBug, aucun cookie de session inclus dans la demande.

Qu'est-ce que je fais mal?

414voto

Kangur Points 2412

Je suis d'exploitation en cross-domain scénario. Lors de la connexion à distance du serveur est de retour en-tête Set-Cookie avec Allow-Access-Control-Credentials la valeur true.

Le prochain appel ajax au serveur distant doit utiliser ce cookie.

La SCRO de l' Access-Control-Allow-Credentials est là pour permettre à la croix-domaine de l'exploitation forestière. Vérifier https://developer.mozilla.org/En/HTTP_access_control pour des exemples.

Pour moi, il semble comme un bug dans JQuery (ou au moins de fonctionnalité dans la prochaine version).

Mise à JOUR:

  1. Les Cookies ne sont pas mis automatiquement à partir de l'AJAX réponse (citation de: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/)

    Pourquoi?

  2. Vous ne pouvez pas obtenir la valeur du cookie de réponse à la définir manuellement (http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader)

    Je suis confus..

    Il doit exister une façon de demander aux jquery.ajax() pour configurer XMLHttpRequest.withCredentials = "true" paramètre.

RÉPONSE: Vous devez utiliser xhrFields param de http://api.jquery.com/jQuery.ajax/

L'exemple de la documentation:

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

235voto

flu Points 3120

Les appels AJAX seulement envoyer des "Cookies" si l'url que vous avez demandé est sur le même domaine que votre script d'appel.

Cela peut être une Croix Problème de Domaine.

Peut-être que vous avez essayé d'appeler une url à partir de www.domain-a.com alors que votre script d'appel était sur www.domain-b.com (En d'autres termes: Vous avez fait une Croix Domaine d'Appel, auquel cas le navigateur ne permet pas l'envoi de cookies pour protéger votre vie privée).

Dans ce cas, vos options sont les suivantes:

  • Écrire un petit proxy qui se trouve sur un domaine b et en avant vos demandes de domaine-un. Votre navigateur vous permettra d'appeler le proxy, car c'est sur le même serveur que le script d'appel.
    Ce proxy alors peut-être que vous avez configurée pour accepter un cookie nom et la valeur de paramètre qu'il peut envoyer à un domaine un. Mais pour que cela fonctionne, vous devez connaître le nom du cookie et la valeur de votre serveur sur un domaine de souhaite pour l'authentification.
  • Si vous êtes à la corvée d'objets JSON essayez d'utiliser un JSONP demande à la place. jQuery permet de ces. Mais vous avez besoin de modifier votre service sur un domaine d'une sorte qu'elle retourne valide JSONP répond.

Heureux si cela a aidé un peu.

51voto

À l'aide de

xhrFields: { withCredentials:true }

dans le cadre de mon appel ajax jQuery n'était qu'une partie de la solution. J'ai aussi besoin d'avoir les en-têtes retournées dans les OPTIONS de réponse de ma ressource:

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

Il était important que seul un permis "d'origine" était dans l'en-tête de réponse de l'appel OPTIONS et pas de "*". Je l'ai réalisé en lisant l'origine de la demande et de l'alimenter de nouveau dans la réponse - probablement de contourner l'original en raison de la restriction, mais dans mon cas d'utilisation, la sécurité n'est pas primordiale.

J'ai pensé qu'il vaut la peine de mentionner explicitement l'exigence d'une seule origine, comme le standard du W3C ne permet pour une liste séparée par des espaces -mais Chrome ne fait pas! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB: le "dans la pratique".

15voto

munchbit Points 136

Il y a déjà beaucoup de bonnes réponses à cette question, mais j'ai pensé qu'il pourrait être utile de clarifier le cas où vous vous attendez à ce que le cookie de session pour être envoyé à cause d'un cookie de domaine matches, mais il n'est pas envoyé parce que l'AJAX demande est faite à un autre sous-domaine. Dans ce cas, j'ai un témoin qui est affectée à l' *.mydomain.com domaine, et je suis désireux d'être inclus dans une requête AJAX different.mydomain.com". Par défaut, le cookie n'est pas envoyé. Vous n'avez pas besoin de désactiver HTTPONLY sur le cookie de session pour résoudre ce problème. Vous avez seulement besoin de faire ce wombling suggéré (http://stackoverflow.com/a/23660618/545223) et effectuez les opérations suivantes.

1) Ajoutez les lignes suivantes à votre requête ajax.

xhrFields: { withCredentials:true }

2) Ajoutez les lignes suivantes à votre en-têtes de réponse pour les ressources dans le sous-domaine différent.

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

4voto

wiwa Points 26

J'ai eu ce même problème et faire quelques vérifications mon script était tout simplement de ne pas obtenir l'id de session cookie.

J'ai trouvé en regardant le sessionid valeur du cookie dans le navigateur de mon cadre (Django) était en train de passer l'id de session cookie avec HttpOnly en tant que par défaut. Cela signifie que les scripts n'ont pas accès à l'id de session de la valeur et, par conséquent, à ne pas la transmettre avec la demande. Un peu ridicule que HttpOnly serait la valeur par défaut alors que tant de choses utiliser Ajax qui nécessiterait de restriction d'accès.

Pour corriger cela, j'ai changé un paramètre (SESSION_COOKIE_HTTPONLY=False), mais dans d'autres cas, il peut être un "HttpOnly" drapeau sur le chemin du cookie

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X