如何处理多个同名的cookie?

dea*_*mon 83 cookies http

比方说,我有一个应用程序发送以下HTTP标头设置为名为"a"的cookie:

Set-Cookie: a=1;Path=/;Version=1
Set-Cookie: a=2;Path=/example;Version=1
Run Code Online (Sandbox Code Playgroud)

如果我/example在服务器上访问这两个路径都是有效的,那么我有两个名为"a"的cookie!由于浏览器不发送任何路径信息,因此无法区分这两个cookie.

Cookie: a=2; a=1
Run Code Online (Sandbox Code Playgroud)

该案件应如何处理?选择第一个?创建一个包含所有cookie值的列表?或者这种情况应该被视为开发人员的错误?

小智 80

关于SitePoint的文章的答案并不完整.请参阅RFC 6265(公平地说,此RFC在发布此问题后于2011年发布,取代之前的2000年RFC 2965和1997年的RFC 2109).

第5.4节第2小节有这样的说法:

用户代理应该按以下顺序对cookie列表进行排序:

  • 在具有较短路径的cookie之前列出具有较长路径的Cookie.

注意:并非所有用户代理都按此顺序对cookie列表进行排序,但此顺序反映了编写此文档时的常见做法,并且历史上存在(错误地)依赖此订单的服务器.

4.2.2节中还有这个小宝石:

...服务器不应该依赖序列化顺序.特别是,如果Cookie标头包含两个具有相同名称的cookie(例如,设置了不同的Path或Domain属性),则服务器不应该依赖于这些cookie在标头中出现的顺序.

在您的示例请求cookie(Cookie:a = 2; a = 1)中请注意,使用路径/示例(a = 2)设置的cookie的路径比路径/(a = 1)的路径长,因此它首先发送给您,这符合规范的建议.因此,在您可以选择第一个值的假设中,您或多或少是正确的.

不幸的是RFC中所使用的语言是非常具体-使用的话应该不应该在RFC中引入歧义.这些表示遵循的约定,但不要求符合规范.虽然我很了解RFC,但我没有做过研究,看看现实世界的客户做了什么; 作为HTTP客户端的一个或多个浏览器或其他软件可能不会首先在Cookie:标头中发送最长路径cookie(例如:/ example).

如果您能够控制cookie的价值并且想要使您的解决方案变得万无一失,那么您最好:

  1. 使用不同的cookie名称覆盖某些路径,例如:

    • Set-cookie:a-global = 1; Path = /; Version = 1
    • Set-cookie:a-example = 2; Path =/example; Version = 1
  2. 在cookie值本身中存储您需要的路径:

    • Set-cookie:a = 1&path = /; Path = /; Version = 1
    • Set-cookie:a = 2&pat​​h =/example; Path =/example; Version = 1

这两种解决方法都需要服务器上的其他逻辑来选择所需的cookie值,方法是将请求的URL与可用cookie列表进行比较.它不太漂亮.这是不幸的RFC没有先见之明,需要一个较长的路径完全覆盖有一个较短的路径一个cookie(例如:在你的榜样,您将收到的Cookie:A = 2 ).

  • 看起来Wildfly 8.0正在关注cookie的顺序并使用第一个.这允许我们在"嵌套"上下文中运行另一个应用程序.但是,如果某些浏览器不遵循RFC的建议,它将失败.正确的方法是设置会话cookie的不同名称,如JSESSIONID2. (3认同)
  • 阅读您的答案后,我确实测试了主要浏览器:Chrome 63 / Opera 55 / IE11 / Edge 16 / Safari 11 / Firefox 58 他们似乎都正确处理了路径较长的 Cookie 在路径较短的 Cookie 之前。而在 PHP(在版本 7 上测试)中,它只读取设置为 $_COOKIE 变量的第一个 cookie。 (3认同)
  • 感谢您从这些该死的RFC中找出来!//如果没有人遵循这些建议,为什么还要打扰他们呢? (2认同)

Jan*_*n M 40

SitePoint上的这篇文章:

如果多个同名的cookie与给定的请求URI匹配,则浏览器选择一个.

路径越具体,优先级越高.但是,基于其他属性(包括域)的优先级未指定,并且可能因浏览器而异.这意味着如果您在".example.org"和"www.example.org"上设置了相同名称的Cookie,则无法确定哪个会被发回.

编辑:2010年的这些信息似乎已经过时,似乎浏览器现在可以发送多个cookie作为回报,请参阅下面的@Nate回答详情

  • @Brant那篇文章可能稍微不正确 - 我刚看到Chrome发回两个同名(但路径不同)的cookie,所以"浏览器选择一个"不一定是真的.最深的路径cookie首先发送,BTW,这似乎是合理的.而另一个cookie也介于两者之间. (13认同)
  • 那么如何删除多个相同的cookie呢?我已经敲了两天了,重复的曲奇饼似乎坚不可摧. (8认同)
  • 404:找不到著名的@Nate 的答案。 (7认同)
  • Firefox(15)也发送两个同名的cookie!如果遇到域名为".a.com"和主机"a.com"的两个cookie (3认同)