在子域和域之间共享Cookie


420

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

可以subdomain.mydomain.com访问在中创建的Cookie mydomain.com(无需www子域)吗?

如果在中创建,可以mydomain.com(没有www子域)访问cookie subdomain.mydomain.com




你可以请你看看这个问题stackoverflow.com/questions/38351769/...
Jayavardhan甘杰

1
@ adam0101如果域和子域托管在不同的服务器上怎么办?
user3782114 '16

3
@ user3782114,它们是否在不同的服务器上无关紧要。就我而言,它们不仅位于不同的服务器上,而且每个域都跨多个服务器进行负载平衡。令我们有些困惑的是,一旦我们这样做,较低的环境(开发,测试,测试环境等)也开始共享相同的cookie,因为我们将它们命名为“ dev.oursite.com”,“ test”。这里的技巧(至少在.Net中)是为每个环境生成一个单独的机器密钥,并将其保存在Web.config中(假设您为每个环境转换了配置)。
adam0101 '16

Answers:


653

这2个域mydomain.comsubdomain.mydomain.com并且只有在Set-Cookie标头中明确命名该域时才能共享cookie 。否则,cookie的范围仅限于请求主机。(这称为“仅主机cookie”。请参阅什么是仅主机cookie?

例如,如果您从发送了以下标头subdomain.mydomain.com,则不会向以下请求发送Cookie mydomain.com

Set-Cookie: name=value

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

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

该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。

也可以看看:


3
谢谢; 我添加了有关点的重要性的注释。
cmbuckley 2014年

2
我不明白您为什么不只在开头加上“。” 在域上实现与新旧版本的最大兼容性
Alan Macdonald

12
在旧标准中,带有的cookie domain=.mydomain.com对于裸mydomain.com无效,因此这两个RFC彼此不兼容。
cmbuckley 2015年

4
@弗兰克,是的,我知道。我的评论是澄清我的问题是关于在域和子域之间共享cookie,而不是在两个子域之间共享cookie。
adam0101 '18

3
我不确定将其放在何处,因此我正在选择已接受答案的评论。在我的本地主机上证明上述内容花费了很长时间,并且实验失败,直到我想到应该使用名称中的一个点来调用本地主机。像“ localhost.com”之类的东西。然后,按照此答案此处编写的说明,开始所有“设置cookie”行为。希望这可能对某人有帮助。
Cesc

32

我不确定@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测试站点,用于那些像我这样回答中错过它的人;值得滚动和赞美/:


4
这似乎与我的意思一致:除非您指定domain,否则cookie仅用于请求主机。这意味着Set-Cookie: name=valuefrom mydomain.com不会与请求一起发送到子域。也可以使用此测试脚本
cmbuckley '16

@cmbuckley,好的,您说的似乎正确。我会改写我的答案。感谢您指出这一点。
akostadinov '16

需要指出的是,第4.1.2节(第一次引用)不是规范性的……
Velda,

感谢cmbuckley链接。很高兴测试它如何快速工作。
lawphotog

22

这是使用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.com以及subdomain.mydomain.com


最后,如果要尝试在subdomain.mydomain.com上执行以下命令:

document.cookie =“ key = value; domain = .mydomain.com”

cookie 密钥可用于subdomain.mydomain.com吗?允许这样做令我有些惊讶;我以为子域能够在父域上设置cookie将违反安全性。


1
这使我想知道是否有单独的规范描述httponlycookie 的行为以及所创建的cookie的类型。
adam0101 '17

3
您发布的文档与您的陈述不符。前两个示例不是等效的(domain属性使cookie在子域上起作用;没有这样的属性就不行)。最好不要忽略前导点,最坏的情况下会主动阻塞。
cmbuckley

如果您不想依赖主机头,这是最好的解决方案。我检查了它及其工作状态
-Szymon,

14

请大家注意,您可以从域中的子域设置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. 满足以下所有条件:

    • 域字符串是字符串的后缀。

    • 域字符串中不包含的字符串的最后一个字符是%x2E(“。”)字符。

    • 该字符串是主机名(即,不是IP地址)。

因此,“ subdomain.mydomain.com”域匹配“ mydomain.com”,但是“ mydomain.com”不域匹配“ subdomain.mydomain.com”

也检查此答案


这对我来说是最有用的答案。
Toby

3

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

其他答案可提供宝贵的见解,但主要描述Chrome中的行为。请务必注意,IE中的行为完全不同。CMBuckley的非常有用的测试脚本表明,在(例如)Chrome浏览器中,未指定域时,不会在根域和子域之间共享cookie。但是,在IE中相同的测试表明它们是共享的。该IE案例更接近CMBuckley的www-or-not-www链接中的概述。我知道是这样,因为我们有一个系统在根域和子域上使用不同的服务堆栈cookie。一切正常,直到有人在IE中访问了它,并且两个系统争夺了其会话cookie,直到我们耗尽了缓存。


0

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

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

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

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

-12

简单的解决方案

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

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

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


17
这个问题不是特定于PHP的,我认为它不符合条件。
sergelerator

1
Sergelerator,我没有提出任何问题。我在回应OP。
Lawes

4
@Lawes我相信中士意味着OP的问题不是特定于PHP的,而您的答案似乎只是PHP的解决方案,因此它不符合OP的问题。
Mirage
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.