Pourquoi est jquery.méthode ajax () ne pas envoyer mon cookie de session?

après m'être connecté via $.ajax() à un site, j'essaie d'envoyer une seconde requête $.ajax() à ce site - mais quand je vérifie les en-têtes envoyés en utilisant FireBug, il n'y a pas de cookie de session inclus dans la requête.

Qu'est-ce que je fais de mal?

298
demandé sur Troy Alford 2010-05-20 04:44:50

10 réponses

les appels AJAX n'envoient des Cookies que si l'url que vous appelez est sur le même domaine que votre script d'appel.

il peut s'agir d'un problème de domaine croisé.

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 un appel de domaine croisé dans lequel cas le navigateur ne sera pas envoyé de cookies pour protéger votre vie privée).

dans ce cas vos options sont:

  • écrivez un petit proxy qui réside sur le domaine-B et transmet vos requêtes au domaine-a. Votre navigateur vous permettra d'appeler le proxy car il est sur le même serveur que le script d'appel.

    ce proxy peut alors être configuré par vous pour accepter un nom de cookie et un paramètre de valeur qu'il peut envoyer à domain-a. Mais pour que cela fonctionne, vous devez connaître le nom du cookie et la valeur de votre serveur sur domain-a wants for authentication.
  • si vous cherchez des objets JSON, essayez d'utiliser une requête JSONP à la place. jQuery les supporte. Mais vous devez modifier votre service sur domain-a pour qu'il renvoie des réponses JSONP valides.

heureux si cela a aidé même un peu.

189
répondu flu 2015-09-14 10:00:09

j'opère dans un scénario de cross-domain. Lors de la connexion, le serveur distant renvoie L'en-tête Set-Cookie ainsi que Access-Control-Allow-Credentials à true.

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

CORS Access-Control-Allow-Credentials est là pour permettre la journalisation croisée. Vérifier https://developer.mozilla.org/En/HTTP_access_control par exemple.

pour moi cela ressemble à un bug dans JQuery (ou au moins fonctionnalité dans la prochaine version).

mise à jour:

  1. les Cookies ne sont pas définis automatiquement à partir de la réponse AJAX (référence: 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 devrait y avoir un moyen de demander à jquery.ajax() de définir le paramètre XMLHttpRequest.withCredentials = "true" .

réponse: Vous devez utiliser xhrFields param de http://api.jquery.com/jQuery.ajax/

l'exemple dans la documentation est:

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

il est également important que le serveur réponde correctement à cette requête. Copier ici de bons commentaires de @Frédéric et @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: *

ainsi quand la demande est:

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

le serveur doit répondre par:

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

[payload]

sinon la charge utile ne sera pas retournée à script. Voir: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials

341
répondu Kangur 2016-03-05 17:51:12

utilisant

xhrFields: { withCredentials:true }

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

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

il était important que seulement un origine" autorisée "soit dans l'en-tête de réponse de L'appel D'OPTIONS et et non "*". J'ai réalisé cela en lisant l'origine de la demande et en la peuplant à nouveau dans le réponse - probablement contourner la raison initiale de la restriction, mais dans mon cas d'utilisation, la sécurité n'est pas primordiale.

j'ai pensé qu'il valait la peine de mentionner explicitement l'exigence pour une seule origine, car la norme W3C permet une liste séparée par espace-mais pas Chrome! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB: le "dans la pratique".

41
répondu wombling - Chris Paine 2014-05-14 16:50:35

mettez ceci dans votre fonction init:

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

ça va marcher.

37
répondu Alex Athlan 2015-03-22 11:20:31

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 soit envoyé parce que le domaine du cookie correspond, mais il ne sera pas envoyé parce que la demande AJAX est faite à un sous-domaine différent. Dans ce cas, j'ai un cookie qui est assigné au *.mydomain.com domaine, et je veux qu'il soit inclus dans une demande 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 n'avez qu'à faire ce que wombling a suggéré ( https://stackoverflow.com/a/23660618/545223 ) et faire ce qui suit.

1) ajouter ce qui suit à votre demande ajax.

xhrFields: { withCredentials:true }

2) ajouter ce qui suit à vos en-têtes de réponse pour les ressources dans les différents sous-domaine.

Access-Control-Allow-Origin : http://original.mydomain.com
Access-Control-Allow-Credentials : true
9
répondu munchbit 2017-05-23 12:26:34

après avoir essayé les autres solutions et ne pas l'avoir fait fonctionner, j'ai découvert quel était le problème dans mon cas. J'ai changé contentType De "application/json" à "text/plain".

$.ajax(fullUrl, {
    type: "GET",
    contentType: "text/plain",
    xhrFields: {
         withCredentials: true
    },
    crossDomain: true
});
4
répondu Janno Teelem 2018-02-23 09:31:25

j'avais ce même problème et faire quelques vérifications mon script ne recevait tout simplement pas le cookie sessionid.

j'ai compris en regardant la valeur du cookie sessionid dans le navigateur que mon framework (Django) passait le cookie sessionid avec HttpOnly par défaut. Cela signifiait que les scripts n'avaient pas accès à la valeur sessionid et ne la transmettaient donc pas avec les requêtes. C'est un peu ridicule que HttpOnly soit la valeur par défaut quand tellement de choses utilisent Ajax qui nécessiterait une restriction d'accès.

pour corriger ceci j'ai changé un paramètre (SESSION_COOKIE_HTTPONLY=False) mais dans d'autres cas il peut s'agir d'un drapeau "HttpOnly" sur le chemin du cookie

3
répondu wiwa 2013-10-12 17:16:23

si vous développez sur localhost ou un port sur localhost tel que localhost:8080 , en plus des étapes décrites dans les réponses ci-dessus, vous devez également vous assurer que vous ne passez pas de valeur de domaine dans L'en-tête Set-Cookie.

Vous ne pouvez pas définir le domaine à localhost dans L'en-tête Set - Cookie - c'est incorrect-il suffit d'omettre le domaine.

voir Cookies sur localhost avec Domaine explicite et Pourquoi ne pas asp.net créer des cookies en localhost?

0
répondu jitin 2017-05-23 11:55:03

Vous devez initialiser la session avant d'essayer de se connecter.

pour php, vous devez faire

session_start();

sur la page à partir de laquelle vous commencez l'appel ajax login.

pour que le SESSIONID soit créé et stocké dans le cookie du navigateur. Et envoyé avec l'en-tête de requête pendant l'appel ajax, si vous faites la requête ajax au même domaine

pour le le navigateur suivant ajax calls utilisera le SESSIONID qui a créé et stocké initialement dans le cookie du navigateur, à moins que nous n'éliminions le cookie du navigateur ou que nous ne fassions une déconnexion (ou paramétrions un autre cookie)

0
répondu Mohammed Safeer 2017-05-27 05:58:35

peut-être pas à 100% répondre à la question, mais je suis tombé sur ce fil dans l'espoir de résoudre un problème de session quand ajax-poster un fichier Upload de l'assetmanager de l'éditeur innovastudio. Finalement, la solution a été simple: ils ont un flash-uploader. Désactiver ce paramètre (paramètre

var flashUpload = false;   

dans asset.php) et les lumières ont recommencé à clignoter.

Que ces problèmes peuvent être très difficiles à déboguer j'ai trouvé que la mise quelque chose comme ce qui suit dans le gestionnaire de téléchargement va vous mettre (moi dans ce cas) sur la bonne voie:

$sn=session_name();
error_log("session_name: $sn ");

if(isset($_GET[$sn])) error_log("session as GET param");
if(isset($_POST[$sn])) error_log("session as POST param");
if(isset($_COOKIE[$sn])) error_log("session as Cookie");
if(isset($PHPSESSID)) error_log("session as Global");

une plongée dans le journal de bord et j'ai rapidement repéré la session manquante, où aucun cookie n'a été envoyé.

-4
répondu Ellert van Koperen 2014-08-04 22:05:54