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

92

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

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

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

Cookie: a=2; a=1

Comment traiter cette affaire? 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?

démon
la source
Je ferais de mon mieux (lire: tout ce que je peux) pour éviter les noms de cookies en double. La plupart des gens n'ont jamais rencontré ce problème - pour une bonne raison.
Le site Web ne peut lire que son propre cookie. Il ne peut pas lire les cookies de l'autre site Web / domaine. Cette sécurité est assurée par le navigateur. Cela peut être une astuce pour les débutants absolus (j'ai eu cette confusion)
Arun

Réponses:

38

De cet article sur SitePoint :

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

Plus le chemin est précis, plus la priorité est élevée. Cependant, 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 défini des cookies du même nom sur «.example.org» et «www.example.org», vous ne pouvez pas être sûr de celui qui sera renvoyé.

Edit: ces informations de 2010 semblent obsolètes, il semble que les navigateurs peuvent désormais envoyer plusieurs cookies en retour, voir la réponse de @Nate ci-dessous pour plus de détails

Jan M
la source
9
Alors, comment supprimer les multiples cookies identiques? J'ai martelé là-dessus pendant deux jours maintenant et les cookies en double semblent indestructibles.
Bob Jones
13
@Brant Cet article est peut-être légèrement incorrect - je viens de voir Chrome renvoyer deux cookies du même nom (mais des chemins différents), donc "l'un est choisi par le navigateur" n'est pas nécessairement vrai. Le cookie de chemin le plus profond a été envoyé en premier, BTW, ce qui semble raisonnable. Et un autre cookie l'a également fait entre les deux.
Jonas N
3
Firefox (15) envoie également deux cookies du même nom! s'il rencontre deux cookies avec pour domaine .a.comet hôtea.com
Taha Jahangir
En effet, cette information est erronée. La réponse de @Nate devrait me marquer comme correcte.
Dan Milon
5
404: La réponse du célèbre @ Nate est introuvable.
d.popov
90

La réponse faisant référence à un article sur SitePoint n'est pas entièrement complète. Veuillez consulter la RFC 6265 (pour être honnête, cette RFC a été publiée en 2011 après la publication de cette question, qui remplace la RFC 2965 précédente de 2000 et la RFC 2109 de 1997).

La section 5.4 , sous-section 2, dit ceci:

L'agent 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 des cookies dans cet ordre, mais cet ordre reflète la pratique courante lors de la rédaction de ce document et, historiquement, il y a eu des serveurs qui dépendaient (à tort) de cet ordre.

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

... les serveurs NE DEVRAIENT PAS s'appuyer sur l'ordre de sérialisation. En particulier, si l'en-tête Cookie contient deux cookies avec le même nom (par exemple, qui ont été définis avec des attributs de chemin ou de domaine différents), les serveurs NE DEVRAIENT PAS s'appuyer 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 donc il vous est renvoyé en premier, ce qui correspond à la recommandation de la spécification. Ainsi, vous avez plus ou moins raison de supposer que vous pourriez sélectionner 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 d'ambiguïté dans les RFC. Celles-ci indiquent les conventions qui doivent être suivies, mais ne sont pas tenues d'être conformes à la spécification. Bien que je comprenne assez bien la RFC pour cela, je n'ai pas fait de recherche pour voir ce que font les clients du monde réel; il est possible qu'un ou plusieurs navigateurs ou autres logiciels agissant en tant que clients HTTP ne puissent pas envoyer le cookie de chemin le plus long (par exemple: / exemple ) en premier dans l'en- tête Cookie :.

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

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

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

    • Set-cookie: a = 1 & path = /; Chemin = /; Version = 1
    • Set-cookie: a = 2 & path = / 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 prévoyance d'exiger qu'un chemin plus long remplace complètement un cookie avec un chemin plus court (par exemple: dans votre exemple, vous recevriez Cookie: a = 2 uniquement ).

Chimpanzé guerrier
la source
2
Merci d'avoir extrait cela de ces foutues RFC! // pourquoi même prendre la peine de les lire si personne ne suit ces recommandations? ..
Rast
3
Il semble que Wildfly 8.0 prête attention à l'ordre des cookies et utilise le premier. Cela nous permet d'exécuter une autre application dans un contexte «imbriqué». Cependant, cela échouerait si certains navigateurs ne suivaient pas les recommandations de la RFC. Une manière correcte de faire cela pour définir un nom différent du cookie de session, comme JSESSIONID2.
honzajde
2
J'ai testé les principaux navigateurs après avoir lu votre réponse: Chrome 63 / Opera 55 / IE11 / Edge 16 / Safari 11 / Firefox 58 Et ils semblent tous gérer correctement le fait que le cookie avec le chemin le plus long soit avant celui avec le chemin le plus court. Et en PHP (testé sur la version 7), il ne lit que le premier cookie défini sur la variable $ _COOKIE.
Alexander Schranz
1
La path=/;Path=/spécification est- elle conforme à FRC-6265? Je n'ai pas trouvé une telle mention. Tomcat menace tout ";" dans le chemin comme symbole incorrect
Hubbitus
1
@Hubbitus Faites attention, il a=2&path=/example;Path=/examplen'y a donc pas ;de chemin.
Franklin Yu
2

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 est d'envoyer le même nom de cookie avec le même chemin (et domaine) même à partir des chemins les plus spécifiques. Ces instructions de cookie définies remplaceront 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: il s'agit d'un problème de développeur.

Gérard ONeill
la source
0

Je connais certainement des applications qui font cela de manière intensive en utilisant plusieurs identifiants de session - et semblent fonctionner de manière cohérente. Cependant, je ne sais pas - et je n'ai pas l'intention de le savoir - s'ils le font car 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 faire correspondre chacun un à une session existante.

Je recommanderais fortement d'éviter cette pratique.

Cependant, si vous voulez vraiment savoir comment les navigateurs (et les applications) gèrent ce scénario, pourquoi ne pas créer une plate-forme de test et l'essayer.

symcbean
la source
2
Un serveur n'a aucun contrôle sur ce qui lui est envoyé par le navigateur. Il doit encore être traité.
Martin OConnor
0

Si vous utilisez le framework Java / Scala Play: attention! Si une demande contient plusieurs cookies du même nom, Play n'en présentera qu'un à votre code.

Erik van Oosten
la source
-2

Si vous avez besoin de les distinguer, vous devez leur attribuer des valeurs clés différentes.

Yaourt
la source