590

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

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

mydomain.com如果在 中创建(没有子域)可以www访问 cookiesubdomain.mydomain.com吗?

4

8 回答 8

920

如果域在标头中明确命名,则两个不同的域(例如mydomain.comand subdomain.mydomain.com,或sub1.mydomain.comand sub2.mydomain.com)只能共享 cookie Set-Cookie。否则,cookie 的范围仅限于请求主机。(这被称为“仅主机 cookie”。请参阅什么是仅主机 cookie?

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

Set-Cookie: name=value

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

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

域属性必须与 URL 中的域“域匹配”才能有效,即该属性必须是同一个域或超域。

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


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

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

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

也可以看看:

于 2014-04-15T14:07:11.507 回答
75

请大家注意,您可以在域的子域中设置 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 第 5.3.6 节存储模型

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

RFC 6265 第 5.1.3 节域匹配

域匹配

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

  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”

也检查这个答案

于 2019-09-05T10:11:52.170 回答
44

我不确定@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 测试站点/对于那些像我一样在他的回答中错过它的人;值得向上滚动和投票/:

于 2016-06-06T11:59:43.603 回答
28

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

如果我们执行以下 JavaScript:

document.cookie = "键=值"

它似乎与执行相同:

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

cookie密钥(仅)在域mydomain.com上可用。


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

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

cookie密钥对mydomain.comsubdomain.mydomain.com都可用。


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

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

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

于 2017-09-26T19:45:53.543 回答
4

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

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

于 2017-06-06T05:57:42.663 回答
4

如果您在 localhost 上工作,请小心!如果您将 cookie 存储在 js 中,如下所示:

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

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

document.cookie = "key=value;domain=localhost.com"
于 2019-12-16T20:20:53.663 回答
-1

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

Cookie.set('key', 'value', { domain: '.facebook.com' })

// adding a . before domain name

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

于 2021-07-26T21:44:21.263 回答
-12

简单的解决方案

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

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

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

于 2016-05-20T13:09:05.747 回答