Como lidar com vários cookies com o mesmo nome?

93

Digamos, por exemplo, que eu tenha um aplicativo enviando os seguintes cabeçalhos HTTP para definir como cookie chamado "a":

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

Se eu acessar /exampleno servidor os dois caminhos são válidos, então tenho dois cookies chamados "a"! Como o navegador não envia nenhuma informação de caminho, os dois cookies não podem ser distinguidos.

Cookie: a=2; a=1

Como esse caso deve ser tratado? Escolha o primeiro? Criar uma lista com todos os valores de cookies? Ou esse caso deve ser considerado um erro do desenvolvedor?

deamon
fonte
Eu faria o meu melhor (leia: tudo o que puder) para evitar nomes de cookies duplicados. A maioria das pessoas nunca se deparou com esse problema - por um bom motivo.
O site só pode ler seu próprio cookie. Ele não pode ler o cookie do outro site / domínio. Esta segurança é garantida pelo navegador. Esta pode ser uma dica para iniciantes (eu tive essa confusão)
Arun

Respostas:

40

Deste artigo no SitePoint :

Se vários cookies com o mesmo nome corresponderem a um determinado URI de solicitação, um será escolhido pelo navegador.

Quanto mais específico for o caminho, maior será a precedência. No entanto, a precedência baseada em outros atributos, incluindo o domínio, não é especificada e pode variar entre os navegadores. Isso significa que se você definiu cookies com o mesmo nome em “.example.org” e “www.example.org”, não pode ter certeza de qual será enviado de volta.

Editar: essas informações de 2010 parecem estar desatualizadas, parece que os navegadores agora podem enviar vários cookies em troca, consulte a resposta de @Nate abaixo para obter detalhes

Jan M
fonte
9
Então, como se pode excluir os vários cookies idênticos? Eu martelei nisso por dois dias e os cookies duplicados parecem indestrutíveis.
Bob Jones
14
@Brant Esse artigo pode estar um pouco incorreto - acabei de ver o Chrome enviar dois cookies com o mesmo nome (mas com caminhos diferentes) de volta, então "um é escolhido pelo navegador" não é necessariamente verdade. O cookie de caminho mais profundo foi enviado primeiro, BTW, o que parece razoável. E outro biscoito também fez no meio.
Jonas N
3
O Firefox (15) também envia dois cookies com o mesmo nome! se encontrou dois cookies com para domínio .a.come hosta.com
Taha Jahangir
Na verdade, essa informação está errada. A resposta de @Nate deve ser marcada como correta.
Dan Milon
5
404: A resposta do famoso @Nate não foi encontrada.
d.popov
93

A resposta referente a um artigo no SitePoint não está totalmente completa. Consulte a RFC 6265 (para ser justo, esta RFC foi lançada em 2011 depois que esta pergunta foi postada, que substitui a RFC 2965 anterior de 2000 e a RFC 2109 de 1997).

Seção 5.4 , subseção 2 tem o seguinte:

O agente do usuário DEVE classificar a lista de cookies na seguinte ordem:

  • Cookies com caminhos mais longos são listados antes dos cookies com caminhos mais curtos.

NOTA: Nem todos os agentes de usuário classificam a lista de cookies nesta ordem, mas essa ordem reflete a prática comum quando este documento foi escrito e, historicamente, houve servidores que (erroneamente) dependiam dessa ordem.

Há também esta pequena joia na seção 4.2.2 :

... os servidores NÃO DEVEM confiar na ordem de serialização. Em particular, se o cabeçalho do Cookie contém dois cookies com o mesmo nome (por exemplo, que foram configurados com diferentes atributos de Caminho ou Domínio), os servidores NÃO DEVEM confiar na ordem em que esses cookies aparecem no cabeçalho.

Em seu cookie de solicitação de exemplo ( Cookie: a = 2; a = 1 ), observe que o cookie definido com o caminho / exemplo ( a = 2 ) tem um caminho mais longo do que aquele com o caminho / ( a = 1 ) e assim é enviado de volta para você primeiro na linha, o que corresponde à recomendação da especificação. Portanto, você está mais ou menos correto em sua suposição de que pode selecionar o primeiro valor.

Infelizmente, a linguagem usada nas RFCs é extremamente específica - o uso das palavras DEVE e NÃO DEVE introduzir ambigüidade nas RFCs. Eles indicam as convenções que devem ser seguidas, mas não precisam estar em conformidade com as especificações. Embora eu compreenda o RFC para isso muito bem, não fiz a pesquisa para ver o que os clientes do mundo real fazem; é possível que um ou mais navegadores ou outros softwares agindo como clientes HTTP não enviem o cookie de caminho mais longo (por exemplo: / exemplo ) primeiro no cabeçalho Cookie : .

Se você está em posição de controlar o valor do cookie e deseja tornar sua solução infalível, é melhor:

  1. usando um nome de cookie diferente para substituir em certos caminhos, como:

    • Set-cookie: a-global = 1; Caminho = /; Versão = 1
    • Set-cookie: a-example = 2; Caminho = / exemplo; Versão = 1
  2. armazenando o caminho de que você precisa no próprio valor do cookie:

    • Set-cookie: a = 1 & path = /; Path = /; Versão = 1
    • Set-cookie: a = 2 & path = / example; Path = / example; Versão = 1

Ambas as soluções alternativas requerem lógica adicional no servidor para selecionar o valor do cookie desejado, comparando o URL solicitado com a lista de cookies disponíveis. Não é muito bonito. É uma pena que o RFC não teve a previsão de exigir que um caminho mais longo substitua completamente um cookie por um caminho mais curto (por exemplo: em seu exemplo, você receberia Cookie: a = 2 apenas ).

Chimpanzé guerreiro
fonte
2
Obrigado por extrair isso dessas RFCs malditas! // por que se preocupar em lê-los se ninguém está seguindo essas recomendações? ..
Rast
3
Parece que o Wildfly 8.0 está prestando atenção na ordem dos cookies e usa o primeiro. Isso nos permite executar outro aplicativo em um contexto 'aninhado'. No entanto, haveria falha se alguns navegadores não seguissem a recomendação RFC. Maneira correta de fazer isso para definir um nome diferente do cookie de sessão, como JSESSIONID2.
honzajde
3
Eu testei os principais navegadores depois de ler sua resposta: Chrome 63 / Opera 55 / IE11 / Edge 16 / Safari 11 / Firefox 58 E todos eles parecem lidar corretamente com o fato de que o Cookie com caminho mais longo está antes do com caminho mais curto. E no PHP (testado na versão 7) ele apenas lê o primeiro cookie que está definido para a variável $ _COOKIE.
Alexander Schranz
1
A path=/;Path=/especificação está em conformidade com o FRC-6265? Não encontrei tal menção. Tomcat ameaça qualquer ";" no caminho como símbolo incorreto
Hubbitus
1
@Hubbitus Preste atenção, é a=2&path=/example;Path=/examplepara que não haja ;caminho.
Franklin Yu
2

Não há nada de errado em ter vários valores para o mesmo nome ... se você quiser. Você pode até inserir contexto adicional no valor.

Do contrário, é claro que nomes diferentes são uma solução se você quiser os dois contextos.

A alternativa é enviar o mesmo nome de cookie com o mesmo caminho (e domínio), mesmo a partir de caminhos mais específicos. Essas instruções definidas para o cookie sobrescreverão o valor desse cookie.

Agora que você sabe a parte mais importante (como eles funcionam) e pode realizar o que precisa de algumas maneiras diferentes, minha resposta à sua pergunta é: este é um problema do desenvolvedor.

Gerard ONeill
fonte
0

Certamente estou ciente de aplicativos que fazem isso extensivamente usando vários IDs de sessão - e parecem funcionar de forma consistente. No entanto, não sei - e não tenho intenção de descobrir - se eles fazem isso porque o navegador retorna os cookies em uma ordem consistente, dependendo de quando eles foram definidos / para qual caminho foram definidos ou se o aplicativo tenta corresponder a cada um um para uma sessão existente.

Eu recomendo fortemente que esta prática seja evitada.

No entanto, se você realmente deseja saber como os navegadores (e aplicativos) lidam com esse cenário, por que não construir um equipamento de teste e experimentá-lo.

symcbean
fonte
2
Um servidor não tem controle sobre o que é enviado a ele pelo navegador. Ainda precisa ser resolvido.
Martin OConnor
0

Se você usa o framework Java / Scala Play: cuidado! Se uma solicitação contiver vários cookies com o mesmo nome, o Play apresentará apenas 1 deles em seu código.

Erik van Oosten
fonte
-2

Se você precisar distingui-los, terá de atribuir-lhes valores-chave diferentes.

Iogurte
fonte