web-dev-qa-db-fra.com

Comment gérer plusieurs cookies avec le même nom?

Supposons, par exemple, qu'une application envoie les en-têtes HTTP suivants pour définir un cookie nommé "a":

Set-Cookie: a=1;Path=/;Version=1
Set-Cookie: a=2;Path=/example;Version=1

Si j'accède à /example sur le serveur, les deux chemins sont valides. J'ai donc deux cookies nommés "a"! Étant donné que le navigateur n’envoie aucune information sur le chemin, les deux cookies ne peuvent pas être distingués.

Cookie: a=2; a=1

Comment cette affaire devrait-elle être traitée? Choisissez le premier? Créer une liste avec toutes les valeurs de cookie? Ou un tel cas devrait-il être considéré comme une erreur du développeur?

80
deamon

De cet article sur SitePoint :

Si plusieurs cookies du même nom correspondent à un URI de requête donné, le navigateur en choisit un.

Plus le chemin est spécifique, plus la priorité est élevée. Toutefois, la priorité basée sur d'autres attributs, y compris le domaine, n'est pas spécifiée et peut varier d'un navigateur à l'autre. Cela signifie que si vous avez configuré des cookies du même nom contre “.example.org” et “www.example.org”, vous ne pouvez pas savoir avec certitude lequel sera renvoyé.

Edit: cette information de 2010 semble être obsolète, il semble que les navigateurs peuvent maintenant envoyer plusieurs cookies en retour, voir la réponse par @Nate ci-dessous pour plus de détails

39
Jan M

La réponse à un article sur SitePoint n'est pas complète. S'il vous plaît voir RFC 6265 (pour être juste, cette RFC a été publiée en 2011 après la publication de cette question, ce qui remplace la précédente RFC 2965 de 2000 et RFC 2109 à partir de 1997).

Section 5.4 , la sous-section 2 dit ceci:

L'agent d'utilisateur DEVRAIT trier la liste de cookies dans l'ordre suivant:

  • Les cookies avec des chemins plus longs sont répertoriés avant les cookies avec des chemins plus courts.

REMARQUE: Tous les agents utilisateurs ne trient pas la liste de cookies dans cet ordre, mais cet ordre correspond à la pratique courante lors de la rédaction de ce document. Historiquement, certains serveurs dépendaient (à tort) de cet ordre.

Il y a aussi ce petit bijou dans la section 4.2.2 :

... les serveurs NE DEVRAIENT PAS compter sur l'ordre de sérialisation. En particulier, si l'en-tête de cookie contient deux cookies portant le même nom (par exemple, définis avec des attributs de chemin ou de domaine différents), les serveurs NE DEVRAIENT PAS compter sur l'ordre dans lequel ces cookies apparaissent dans l'en-tête.

Dans votre exemple de cookie de demande ( Cookie: a = 2; a = 1), notez que le cookie défini avec le chemin /exemple ( a = 2) a un chemin plus long que celui avec le chemin / ( a = 1) et il vous est donc renvoyé en première ligne, ce qui correspond à la recommandation de la spécification. Ainsi, vous êtes plus ou moins correct dans votre hypothèse selon laquelle vous pouvez sélectionnez la première valeur.

Malheureusement, le langage utilisé dans les RFC est extrêmement spécifique - l’utilisation des mots [~ # ~] devrait [~ # ~] et NE DEVRAIT PAS introduire une ambiguïté dans RFC. Celles-ci indiquent que les conventions qui devrait doivent être suivies, mais ne sont pas requis pour être conformes à la spécification. Bien que je comprenne très bien le RFC, je n'ai pas fait de recherche pour voir ce que font les clients dans le monde réel; il est possible qu'un ou plusieurs navigateurs ou autres logiciels faisant office de clients HTTP ne puissent pas envoyer le cookie ayant le chemin le plus long (par exemple: /exemple) en premier dans le Cookie: entête.

Si vous êtes en mesure de contrôler la valeur du cookie et que vous souhaitez que votre solution soit infaillible, il vaut mieux:

  1. en utilisant un nom de cookie différent à remplacer dans certains chemins, tels que:

    • Set-cookie: a-global = 1; Chemin = /; Version = 1
    • Set-cookie: a-example = 2; Path =/exemple; Version = 1
  2. stocker le chemin dont vous avez besoin dans la valeur de cookie elle-même:

    • Set-cookie: a = 1 & chemin = /; chemin = /; version = 1
    • Set-cookie: a = 2 & chemin =/exemple; Chemin =/exemple; Version = 1

Ces deux solutions de contournement nécessitent une logique supplémentaire sur le serveur pour sélectionner la valeur de cookie souhaitée, en comparant l'URL demandée à la liste des cookies disponibles. Ce n'est pas trop joli Il est regrettable que la RFC n’ait pas eu la clairvoyance d’exiger qu’un chemin plus long remplace complètement un cookie avec un chemin plus court (par exemple: dans votre exemple, vous recevrez Cookie: a = 2 seulement ).

79
user2609094

Je suis certainement au courant des applications qui utilisent beaucoup d'identifiants de session et qui fonctionnent régulièrement. Cependant, je ne sais pas - et je n'ai pas l'intention de le savoir - s'ils le font parce que le navigateur renvoie les cookies dans un ordre cohérent, en fonction du moment où ils ont été définis/du chemin pour lequel ils ont été définis ou si l'application essaie de les faire correspondre. un à une session existante.

Je recommande fortement que cette pratique soit évitée.

Cependant, si vous voulez vraiment savoir comment les navigateurs (et les applications) gèrent ce scénario, pourquoi ne pas construire un banc d'essai et l'essayer.

0
symcbean

Il n'y a rien de mal à avoir plusieurs valeurs pour le même nom ... si vous les voulez. Vous pouvez même intégrer un contexte supplémentaire dans la valeur.

Si vous ne le faites pas, alors bien sûr, des noms différents sont une solution si vous voulez les deux contextes.

L'alternative consiste à envoyer le même nom de cookie avec le même chemin (et le même domaine), même à partir de chemins plus spécifiques. Ces instructions de cookie définies écraseront la valeur de ce cookie.

Maintenant que vous connaissez la partie la plus importante (comment ils fonctionnent) et que vous pouvez accomplir ce dont vous avez besoin de différentes manières, ma réponse à votre question est la suivante: il s’agit d’un problème de développeur.

0
Gerard ONeill