如何处理多个同名的cookie?

时间:2010-10-29 22:19:24

标签: http cookies

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

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

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

Cookie: a=2; a=1

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

6 个答案:

答案 0 :(得分:76)

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

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

  

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

     
      
  • 路径较长的Cookie会在路径较短的Cookie之前列出。
  •   
     

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

第4.2.2节中还有这个小宝石:

  

...服务器不应该依赖序列化顺序。在   特别是,如果Cookie标头包含两个相同的cookie   名称(例如,使用不同的路径或域属性设置),   服务器不应该依赖于这些cookie在标题中出现的顺序。

在您的示例请求Cookie( Cookie:a = 2; a = 1 )中,请注意使用路径 / example 设置的Cookie( a = 2 )的路径比路径 / a = 1 )的路径长,所以它首先在线发回给你,这与规范的推荐。因此,在您可以选择第一个值的假设中,您或多或少是正确的。

不幸的是,RFC中使用的语言非常具体 - 使用 SHOULD 不应该这些词会在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& path = / example; Path = / example; Version = 1
  3. 通过将请求的URL与可用cookie列表进行比较,这两种解决方法都需要服务器上的其他逻辑来选择所需的cookie值。它不太漂亮。令人遗憾的是,RFC没有先见之明要求更长的路径完全覆盖具有较短路径的cookie(例如:在您的示例中,您将收到 Cookie:a = 2 only < /强>)。

答案 1 :(得分:37)

来自this article on SitePoint

  

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

     

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

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

答案 2 :(得分:0)

我当然知道使用多个会话ID广泛执行此操作的应用程序 - 并且似乎一致地工作。但是我不知道 - 并且无意发现 - 如果他们这样做是因为浏览器以一致的顺序返回cookie,具体取决于它们的设置时间/设置的路径或者应用是否尝试匹配每个一个现有会议。

我强烈建议避免这种做法。

但是,如果你真的想知道浏览器(和应用程序)如何处理这种情况,为什么不建立一个测试装备并试一试。

答案 3 :(得分:0)

为同一个名称设置多个值没有任何问题...如果您需要它们。您甚至可以在值中嵌入其他上下文。

如果你不这样做,那么当然如果你想要两个上下文,不同的名字就是一个解决方案。

另一种方法是使用相同的路径(和域)发送相同的cookie名称,甚至从更具体的路径发送。那些设置的cookie指令将覆盖该cookie的值。

现在您已经了解了最重要的部分(它们如何工作),并且您可以通过几种不同的方式完成所需的工作,我对您的问题的回答是:这是一个开发人员问题。

答案 4 :(得分:0)

如果您使用Java / Scala框架,请执行以下操作:注意!如果请求中包含多个同名Cookie,则Play只会在您的代码中显示其中的1个。

答案 5 :(得分:-1)

如果你需要区分它们,你必须给它们不同的键值。