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

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

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


当前回答

我这样做,对我很有效:

Cookie.set('token', 'some jwt-token', { expire:50000, domain: 'example.com' })

其他回答

如果您正在使用localhost,请小心! 如果你像这样在JavaScript中存储你的cookie:

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

它可能无法被子域访问,比如sub.localhost。为了解决这个问题,你需要使用VirtualHost。例如,你可以用服务器名localhost.com配置你的虚拟主机,然后你就可以像这样在你的域和子域上存储你的cookie:

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

下面是一个使用DOM cookie API的示例,因此我们可以自己查看行为。

如果我们执行以下JavaScript代码,

文件。cookie =“键=值”

它看起来和执行是一样的:

文档。Cookie = "key=value;domain=example.com"

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


现在,如果您在example.com上执行以下JavaScript代码,

文档。Cookie = "key=value;domain=。example.com"

cookie密钥将对example.com和subdomain.example.com可用。


最后,如果您尝试在subdomain.example.com上执行以下命令,

文档。Cookie = "key=value;domain=。example.com"

cookie密钥对subdomain.example.com可用吗?我有点惊讶,这是允许的;我假定子域能够在父域上设置cookie会违反安全。

请大家注意,你可以在一个域上设置一个子域的cookie。

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

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

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

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

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

Why?

根据RFC 6265章节5.3.6存储模型,

如果规范化的request-host与domain-attribute不匹配:完全忽略cookie并中止这些步骤。

和RFC 6265章节5.1.3域匹配,

Domain Matching A string domain-matches a given domain string if at least one of the following conditions hold: The domain string and the string are identical. (Note that both the domain string and the string will have been canonicalized to lower case at this point.) All of the following conditions hold: * 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.example.com域名匹配example.com,但example.com不匹配subdomain.example.com

也检查一下这个答案。

在这两种情况下,是的,它可以,这是Internet Explorer和Edge的默认行为。

其他答案增加了有价值的见解,但它们主要描述了Chrome的行为。需要注意的是,这种行为在ie中是完全不同的。CMBuckley的非常有用的测试脚本演示了在Chrome中,当没有指定域时,cookie不会在根域和子域之间共享。

但是,在Internet Explorer中进行的相同测试显示它们是共享的。这个ie案例更接近CMBuckley的www-or-not-www链接中的详细描述。我知道这是事实,因为我们的系统在根域和子域上都使用了不同的服务堆栈cookie。这一切都很正常,直到有人在Internet Explorer中访问它,两个系统为谁的会话cookie将获胜而争吵,直到我们炸毁了缓存。

我不确定cmbuckley的回答是全面的。我读到的是:

除非cookie的属性另有指示,否则cookie就是 只返回到源服务器(而不是,例如,任何 子域),并且在当前会话结束时过期(如 由用户代理定义)。用户代理忽略未识别的cookie。 RFC 6265

Also

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提供的令人敬畏的饼干测试网站,对于那些像我一样错过了他的答案的人;值得往上翻。

饼干测试