【问题标题】:Share cookie between subdomain and domain在子域和域之间共享 cookie
【发布时间】:2013-08-31 19:15:45
【问题描述】:

我有两个问题。我知道如果我在 cookie 中将域指定为 .mydomain.com(带有前导点),那么所有子域都可以共享一个 cookie。

subdomain.mydomain.com 可以访问在mydomain.com 中创建的cookie(没有www 子域)吗?

mydomain.com(不带www 子域)能否访问在subdomain.mydomain.com 中创建的cookie?

【问题讨论】:

  • 是的,你可以..请参阅下面的链接codeguru.com/csharp/csharp/cs_internet/article.php/c19417/…
  • @adam0101 如果域和子域托管在不同的服务器上怎么办?
  • @user3782114,它们是否在不同的服务器上并不重要。就我而言,它们不仅位于不同的服务器上,而且每个域都在多台服务器上进行负载平衡。让我们有些吃惊的是,一旦我们这样做,较低的环境(dev、test、uat 等)也开始共享相同的 cookie,因为我们将它们命名为“dev.oursite.com”、“test. oursite.com”等。那里的技巧(至少在 .Net 中)是为每个环境生成一个单独的机器密钥并将其保存在您的 Web.config 中(假设您为每个环境转换配置)。跨度>

标签: http cookies subdomain


【解决方案1】:

两个不同的域(例如mydomain.comsubdomain.mydomain.com,或sub1.mydomain.comsub2.mydomain.com)只有在Set-Cookie 标头中明确命名域时才能共享cookie。否则,cookie 的范围仅限于请求主机。 (这被称为“仅限主机的 cookie”。请参阅 What is a host only cookie?

例如,如果您从 subdomain.mydomain.com 发送了以下标头,那么 cookie 将仅针对向该域的请求发送,而不会针对向任何其他域的请求发送:

Set-Cookie: name=value

但是,如果您使用以下内容,它将在两个域中都可用:

Set-Cookie: name=value; domain=mydomain.com

域属性必须是 URL 中的域“domain-match”才有效,即属性必须是同一个域或超域。

然后,上面的 cookie 将被发送到 mydomain.com 的 any 子域,包括嵌套的子域,例如 subsub.subdomain.mydomain.com


RFC 2109 中,没有前导点的域意味着它不能在子域上使用,只有前导点 (.mydomain.com) 才可以跨多个子域使用(但不是顶级域,所以你问的问题在旧规范中是不可能的)。

但是,所有现代浏览器都遵循较新的规范 RFC 6265,并且会忽略任何前导点,这意味着您可以在子域和顶级域上使用 cookie。

总而言之,如果您从mydomain.com 设置像上面第二个示例一样的cookie,则subdomain.mydomain.com 可以访问它,反之亦然。这也可用于允许sub1.mydomain.comsub2.mydomain.com 共享cookie。

另见:

【讨论】:

  • 我不明白你为什么不把开头的“。”在域上最大限度地兼容新旧
  • 在旧标准中,domain=.mydomain.com 的 cookie 对于裸 mydomain.com 无效,因此这两个 RFC 互不兼容。
  • @Frank,是的,我知道。我的评论是为了澄清我的问题是关于在域和子域之间共享 cookie,而不是在两个子域之间。
  • @shi 是的——请看最后一句:“这也可以用来允许sub1.mydomain.comsub2.mydomain.com共享cookie。”
  • 我不确定该放在哪里,所以我选择了已接受答案的 cmets。在我的本地主机上证明上述内容需要很长时间并且实验失败,直到我想到我应该在名称中使用一个点来调用本地主机。像“localhost.com”或类似的东西。然后所有的“设置cookies”行为都按照这个答案中写的解释开始。希望这可能对某人有所帮助。
【解决方案2】:

简单的解决方案

setcookie("NAME", "VALUE", time()+3600, '/', EXAMPLE.COM);

Setcookie 的第 5 个参数确定 cookie 可用于的(子)域。将其设置为 (EXAMPLE.COM) 使其可用于任何子域(例如:SUBDOMAIN.EXAMPLE.COM)

参考:http://php.net/manual/en/function.setcookie.php

【讨论】:

  • 这个问题不是 PHP 特有的,我不认为它是有效的。
  • Sergelerator,我没有提出问题。我正在回复 OP。
  • @Lawes 我相信 sergelator 意味着 OP 的问题不是 PHP 特有的,而您的答案似乎是一个仅限 PHP 的解决方案,因此它不符合 OP 的问题。
【解决方案3】:

我不确定@cmbuckley 的答案是否显示了全貌。我读的是:

除非 cookie 的属性另有说明,否则 cookie 是 仅返回到原始服务器(而不是,例如,任何 子域),并在当前会话结束时到期(如 由用户代理定义)。用户代理会忽略无法识别的 cookie。

RFC 6265

还有

8.6.  Weak Integrity

   Cookies do not provide integrity guarantees for sibling domains (and
   their subdomains).  For example, consider foo.example.com and
   bar.example.com.  The foo.example.com server can set a cookie with a
   Domain attribute of "example.com" (possibly overwriting an existing
   "example.com" cookie set by bar.example.com), and the user agent will
   include that cookie in HTTP requests to bar.example.com.  In the
   worst case, bar.example.com will be unable to distinguish this cookie
   from a cookie it set itself.  The foo.example.com server might be
   able to leverage this ability to mount an attack against
   bar.example.com.

对我来说,这意味着您可以保护 cookie 不被子域/域读取,但不能阻止将 cookie 写入其他域。因此,有人可能会通过控制同一浏览器访问的另一个子域来重写您的站点 cookie。这可能不是一个大问题。

@cmbuckley 提供的很棒的 cookie 测试站点/对于像我这样在他的回答中错过它的人;值得向上滚动和投票/:

【讨论】:

  • 这看起来与我所说的一致:除非您指定 domain,否则 cookie 仅用于请求主机。这意味着来自mydomain.comSet-Cookie: name=value 不会与对子域的请求一起发送。和this test script 一起玩吧。
  • @cmbuckley,好的,你说的似乎是正确的。我会改写我的答案。感谢您指出这一点。
  • 需要指出,第4.1.2节(第一次引用)不规范...
  • 感谢 cmbuckley 链接。很高兴测试它如何快速工作。
【解决方案4】:

在这两种情况下都可以,这是 IE 和 Edge 的默认行为。

其他答案增加了有价值的见解,但主要描述了 Chrome 中的行为。重要的是要注意 IE 中的行为完全不同。 CMBuckley 非常有用的测试脚本演示了在(比如)Chrome 中,当没有指定域时,cookie 不会在根域和子域之间共享。但是 IE 中的相同测试表明它们是共享的。这个 IE 案例更接近 CMBuckley 的 www-or-not-www 链接中的实际描述。我知道是这种情况,因为我们有一个系统在根域和子域上都使用了不同的 servicestack cookie。这一切都很好,直到有人在 IE 中访问它并且两个系统争夺谁的会话 cookie 将获胜,直到我们炸毁缓存。

【讨论】:

    【解决方案5】:

    这是一个使用 DOM cookie API (https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie) 的示例,因此我们可以自己查看行为。

    如果我们执行以下 JavaScript:

    document.cookie = "key=value"

    好像和执行一样:

    document.cookie = "key=value;domain=mydomain.com"

    cookie key 变为(仅)在域 mydomain.com 上可用。


    现在,如果您在 mydomain.com 上执行以下 JavaScript:

    document.cookie = "key=value;domain=.mydomain.com"

    cookie key 可供 mydomain.com 以及 subdomain.mydomain.com 使用。


    最后,如果您要尝试在 subdomain.mydomain.com 上执行以下操作:

    document.cookie = "key=value;domain=.mydomain.com"

    cookie key 是否对 subdomain.mydomain.com 可用?我有点惊讶这是允许的。我曾认为子域能够在父域上设置 cookie 会违反安全性。

    【讨论】:

    • 这让我想知道是否有单独的规范描述 httponly cookie 的行为与您创建的 cookie 的类型。
    • 您发布的文档与您所做的声明不符。前 2 个示例 等效(domain 属性导致 cookie 在子域上工作;没有这样的属性不会)。前导点充其量会被忽略,最坏的情况会被主动屏蔽。
    • 如果您不想依赖主机标头,这是最好的解决方案。我检查了它及其工作
    【解决方案6】:

    请大家注意,您可以在域的子域中设置 cookie。

    (在请求subdomain.mydomain.com的响应中发送)

    Set-Cookie: name=value; Domain=mydomain.com // GOOD
    

    但是您不能在子域上设置域中的 cookie。

    (在请求mydomain.com的响应中发送)

    Set-Cookie: name=value; Domain=subdomain.mydomain.com // Browser rejects cookie
    

    为什么?

    根据规范RFC 6265 section 5.3.6 Storage Model

    如果规范化的请求主机不域匹配域属性:完全忽略 cookie 并中止这些步骤。

    RFC 6265 section 5.1.3 Domain Matching

    域匹配

    如果至少满足以下条件之一,则字符串域匹配给定域字符串:

    1. 域字符串和字符串相同。 (请注意,两者 域字符串和字符串将被规范化为 此时小写。)

    2. 以下所有条件都成立:

      *  The domain string is a suffix of the string.
    
      *  The last character of the string that is not included in the
         domain string is a %x2E (".") character.
    
      *  The string is a host name (i.e., not an IP address).
    

    所以“subdomain.mydomain.com”域匹配“mydomain.com”,但“mydomain.com”不匹配“subdomain.mydomain.com”

    也检查this answer

    【讨论】:

    • 这对我来说是最有帮助的答案。
    • 感谢您提供 documented 答案,该答案为 RFC refs 解释了浏览器何时应该接受 cookie 域,以及为什么“foo.domain.com”可以接受为“domain.com”设置 cookie,即使这似乎违反了“同源策略”并且可能被视为安全风险。
    • 这是我的理解方式,它可以在本地设置,但是一旦我部署到测试环境,除非我删除域属性,否则不再设置 cookie,如果你可以看看我的问题这里stackoverflow.com/questions/69865370/…
    • 值得指出的是,您可以在任何超级域上设置 cookie,但不包括 TLD。例如,您不能使用domain=com。这很明显,但是有一个无法使用的域列表:publicsuffix.org
    【解决方案7】:

    如果您在 localhost 上工作,请小心! 如果你把你的cookie存储在js中是这样的:

    document.cookie = "key=value;domain=localhost"
    

    您的子域可能无法访问它,例如sub.localhost。为了解决这个问题,您需要使用Virtual Host。例如,您可以使用 ServerName localhost.com 配置您的虚拟主机,然后您就可以将您的 cookie 存储在您的域和子域中,如下所示:

    document.cookie = "key=value;domain=localhost.com"
    

    【讨论】:

    • 啊哈!也许这是我的问题。
    • 在 Windows 上,您只需修改您的 hosts 文件并为 localhost 设置您想要的任何别名。例如,local.mydomain.com
    【解决方案8】:

    实际上,就我而言,我想在 test.irsd.test.ir 域和子域之间共享 cookie 数据,以便在我使用 js-cookie 的浏览器中轻松使用 cookie 并模仿 Facebook 解决方案:

    Cookie.set('key', 'value', { domain: '.facebook.com' })
    
    // adding a . before domain name
    

    通过上述代码设置,您可以访问基域和子域中的 cookie 数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 2017-07-14
      • 2021-03-23
      • 2016-08-16
      相关资源
      最近更新 更多