¿Cómo manejar varias cookies con el mismo nombre?

92

Digamos, por ejemplo, que tenía una aplicación que enviaba los siguientes encabezados HTTP para configurar una cookie llamada "a":

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

Si accedo /exampleal servidor, ambas rutas son válidas, ¡así que tengo dos cookies llamadas "a"! Dado que el navegador no envía ninguna información de ruta, no se pueden distinguir las dos cookies.

Cookie: a=2; a=1

¿Cómo se debe manejar este caso? ¿Elige el primero? ¿Crear una lista con todos los valores de las cookies? ¿O debería considerarse tal caso como un error del desarrollador?

demonio
fuente
Haría todo lo posible (lea: todo lo que pueda) para evitar nombres de cookies duplicados. La mayoría de las personas nunca se han encontrado con este problema, por una buena razón.
El sitio web solo puede leer su propia cookie. No puede leer las cookies del otro sitio web / dominio. Esta seguridad está garantizada por el navegador. Este puede ser un consejo para principiantes absolutos (tuve esta confusión)
Arun

Respuestas:

38

De este artículo en SitePoint :

Si varias cookies del mismo nombre coinciden con un URI de solicitud determinado, el navegador elige una.

Cuanto más específica sea la ruta, mayor será la precedencia. Sin embargo, la precedencia basada en otros atributos, incluido el dominio, no está especificada y puede variar entre los navegadores. Esto significa que si ha configurado cookies del mismo nombre para “.example.org” y “www.example.org”, no puede estar seguro de cuál se devolverá.

Editar: esta información de 2010 parece estar desactualizada, parece que los navegadores ahora pueden enviar múltiples cookies a cambio, vea la respuesta de @Nate a continuación para obtener más detalles

Jan M
fuente
9
Entonces, ¿cómo se pueden eliminar las múltiples cookies idénticas? He estado trabajando en esto durante dos días y las cookies duplicadas parecen indestructibles.
Bob Jones
13
@Brant Ese artículo puede ser un poco incorrecto. Acabo de ver que Chrome enviaba dos cookies con el mismo nombre (pero diferentes rutas), por lo que "el navegador elige una" no es necesariamente cierto. La cookie de ruta más profunda se envió primero, por cierto, lo que parece razonable. Y otra galleta también lo hizo en el medio.
Jonas N
3
¡Firefox (15) también envía dos cookies con el mismo nombre! si se encontró con dos cookies para dominio .a.comy hosta.com
Taha Jahangir
De hecho, esta información es incorrecta. La respuesta de @Nate debería marcarme como correcta.
Dan Milon
4
404: No se encuentra la respuesta del famoso @ Nate.
d.popov
90

La respuesta que hace referencia a un artículo en SitePoint no está del todo completa. Consulte RFC 6265 (para ser justos, este RFC se publicó en 2011 después de que se publicara esta pregunta, que reemplaza al RFC 2965 anterior de 2000 y al RFC 2109 de 1997).

La sección 5.4 , subsección 2 tiene esto que decir:

El agente de usuario DEBE ordenar la lista de cookies en el siguiente orden:

  • Las cookies con rutas más largas se enumeran antes que las cookies con rutas más cortas.

NOTA: No todos los agentes de usuario clasifican la lista de cookies en este orden, pero este orden refleja una práctica común cuando se escribió este documento e, históricamente, ha habido servidores que (erróneamente) dependían de este orden.

También está esta pequeña joya en la sección 4.2.2 :

... los servidores NO DEBEN depender del orden de serialización. En particular, si el encabezado de la cookie contiene dos cookies con el mismo nombre (por ejemplo, que se establecieron con diferentes atributos de ruta o dominio), los servidores NO DEBEN depender del orden en el que aparecen estas cookies en el encabezado.

En su cookie de solicitud de ejemplo ( Cookie: a = 2; a = 1 ) tenga en cuenta que la cookie configurada con la ruta / ejemplo ( a = 2 ) tiene una ruta más larga que la que tiene la ruta / ( a = 1 ) y por lo tanto se le envía el primero en la fila, que coincide con la recomendación de la especificación. Por lo tanto, está más o menos en lo correcto al suponer que podría seleccionar el primer valor.

Desafortunadamente, el lenguaje utilizado en las RFC es extremadamente específico: el uso de las palabras DEBE y NO DEBE introducir ambigüedad en las RFC. Estos indican convenciones que deben seguirse, pero no es necesario que cumplan con la especificación. Si bien entiendo el RFC para esto bastante bien, no he hecho la investigación para ver qué hacen los clientes del mundo real; Es posible que uno o más navegadores u otros softwares que actúen como clientes HTTP no envíen la cookie de ruta más larga (por ejemplo: / ejemplo ) primero en el encabezado Cookie:.

Si está en condiciones de controlar el valor de la cookie y desea que su solución sea infalible, lo mejor es:

  1. usando un nombre de cookie diferente para anular en ciertas rutas, como:

    • Establecer-cookie: a-global = 1; Ruta = /; Versión = 1
    • Set-cookie: a-example = 2; Ruta = / ejemplo; Versión = 1
  2. almacenar la ruta que necesita en el valor de la cookie en sí:

    • Establecer-cookie: a = 1 & ruta = /; Ruta = /; Versión = 1
    • Set-cookie: a = 2 & ruta = / ejemplo; Ruta = / ejemplo; Versión = 1

Ambas soluciones requieren lógica adicional en el servidor para elegir el valor de cookie deseado, comparando la URL solicitada con la lista de cookies disponibles. No es demasiado bonito. Es lamentable que el RFC no haya tenido la previsión de requerir que una ruta más larga anule por completo una cookie con una ruta más corta (por ejemplo: en su ejemplo, recibiría Cookie: a = 2 solamente ).

Chimpancé belicoso
fuente
2
¡Gracias por sacar esto de estos malditos RFC! // ¿Por qué molestarse en leerlos si nadie sigue estas recomendaciones? ..
Rast
3
Parece que Wildfly 8.0 está prestando atención al orden de las cookies y utiliza la primera. Esto nos permite ejecutar otra aplicación en un contexto 'anidado'. Sin embargo, fallaría si algunos navegadores no siguen la recomendación de RFC. La forma correcta de hacer esto para establecer un nombre diferente de la cookie de sesión, como JSESSIONID2.
honzajde
2
Probé los principales navegadores después de leer su respuesta: Chrome 63 / Opera 55 / IE11 / Edge 16 / Safari 11 / Firefox 58 Y todos parecen manejarlo correctamente, ya que la cookie con una ruta más larga está antes que la que tiene una ruta más corta. Y en PHP (probado en la versión 7) solo lee la primera cookie que está configurada en la variable $ _COOKIE.
Alexander Schranz
1
¿ path=/;Path=/Cumple la especificación FRC-6265? No encontré tal mención. Tomcat amenaza cualquier ";" en la ruta como símbolo incorrecto
Hubbitus
1
@Hubbitus Presta atención, es a=2&path=/example;Path=/exampleasí que no hay ;camino.
Franklin Yu
2

No hay nada de malo en tener varios valores para el mismo nombre ... si los quiere. Incluso puede insertar contexto adicional en el valor.

Si no lo hace, por supuesto, diferentes nombres son una solución si desea ambos contextos.

La alternativa es enviar el mismo nombre de cookie con la misma ruta (y dominio) incluso desde las rutas más específicas. Las instrucciones establecidas para las cookies sobrescribirán el valor de esa cookie.

Ahora que conoce la parte más importante (cómo funcionan) y que puede lograr lo que necesita de diferentes maneras, mi respuesta a su pregunta es: este es un problema de desarrollador.

Gerard ONeill
fuente
0

Ciertamente estoy al tanto de las aplicaciones que hacen esto de manera extensiva utilizando múltiples identificadores de sesión, y parecen funcionar de manera consistente. Sin embargo, no sé, y no tengo la intención de averiguarlo, si lo hacen porque el navegador devuelve las cookies en un orden coherente según cuándo se establecieron / para qué ruta se establecieron o si la aplicación intenta hacer coincidir cada uno. uno a una sesión existente.

Recomiendo encarecidamente que se evite esta práctica.

Sin embargo, si realmente desea saber cómo los navegadores (y las aplicaciones) manejan este escenario, ¿por qué no construir un equipo de prueba y probarlo?

symcbean
fuente
2
Un servidor no tiene control sobre lo que le envía el navegador. Todavía necesita ser manejado.
Martin OConnor
0

Si usa el framework Java / Scala Play: ¡cuidado! Si una solicitud contiene varias cookies con el mismo nombre, Play solo presentará 1 de ellas en su código.

Erik van Oosten
fuente
-2

Si necesita distinguirlos, debe asignarles valores clave diferentes.

Yogur
fuente