跨子域名和主机的Cookies

16

在我编写的应用程序中,使用多种开发环境和语言的组合时,我需要从两个不同的子域访问cookie,每个子域位于单独的主机上。

使用以下PHP代码将cookie设置在www.mydomain.com上,并尝试从单独的主机distant.mydomain.com访问它。

setcookie('token', base64_encode(serialize($token)), time()+10800, '/', '.mydomain.com');  

我正尝试使用以下代码访问来自distant.mydomain.com的cookie:

if (isset($_COOKIE['token'])) { /* do stuff */ }  

问题: distant.mydomain.com 找不到 cookie。即使 cookie 存在,刚刚提到的 if 语句返回 false。

我已经验证设置的 cookie 是针对 mydomain.com 的(通过检查我的 Firefox cookie)。我想不出任何理由它为什么不能工作。

使用相同的 setcookie 代码,我有一个旧应用程序,专门在 www.mydomain.com 主机上运行,该应用程序能够跨域访问 cookie。这让我怀疑问题与不同的主机有关。

如果以下任何信息相关,请告诉我:
- www.mydomain.com 是 IIS 6.0
- distant.mydomain.com 是 Apache 2.2.9
- 两个服务器都使用 PHP 5.2.x
- 两个服务器都在 Windows Server 2003 上运行

如果需要提供更多信息以更好地描述问题,请告诉我!


抱歉,我还没有弄清楚为什么当我点击提交时,我的帖子的后半部分没有传送过去。 - nmjk
虽然还没有问题 :) - kender
该死!你知道第二次写帖子/电子邮件/任何东西时,永远不会像第一次那样好吗?去编辑 - nmjk
5个回答

12

为了让阅读此问题的人受益,原始帖子中包含的代码和信息完全正确,并且可以正常工作。

问题是当引入其他技术时。例如,我后来发现通过一个Python模块将PHP代码发送到允许Django提供PHP文件/内容的模块会大大改变脚本中可以访问的内容和无法访问的内容。

最终是在Marc Novakowski的建议下发现了这一点,他建议将$_COOKIE发送到登录以查看其中的内容。

我还检查了$_SERVER$_GET。正是$_GET为空提醒了我,我尝试使用的设置并不像我想象的那么简单。正是这种错误的理解导致在原始帖子中未包含有关Django的信息。

对于所有回答此问题的人,我深表歉意和感谢!


4

在域名

'.aaa.sub.domain.com'

设置的Cookies将与在域名中相同名称的Cookies发生冲突

'.sub.domain.com'

'.some.stupidly.obscure.multi.sub.domain.com'

这意味着(并且需要一些时间来解决),如果你要在多个域中使用相同名称的Cookie,你必须在主/基础域中只设置一次,即在本例中为'.domain.com'。否则,结果将不确定地随机返回到某个Cookie,有时是在.a.sub.domain.com中设置的“jasper” Cookie,有时是在.sub.domain.com中设置的“jasper” Cookie,有时是在.b.c.d.domain.com中设置的“jasper” Cookie,有时是在 '.sub.domain.com' 和有时是在 '.domain.com' 中设置的“jasper” Cookie。


3

一个子域名是否使用下划线?IE在接受不遵循URI RFC的子域名的cookie时会出现问题。

这是假设“distant”是占位符而不是实际的子域名,并且你使用IE。虽然更多的浏览器可能会受到影响,但Fireworks并不会。


实际域名中有一个连字符,但所有其他字符都是字母。所讨论的子域名仅为字母。 - nmjk

1
我会尝试安装Charles Proxy,看看首先发送到Firefox的标头(以设置Cookie)以及从Firefox发送到第二个服务器的哪些标头。至少这样你可以缩小问题出现的范围(是浏览器还是服务器)。

有用的工具!我看了一下,尽管请求distant.mydomain.com和local.mydomain.com(可以读取cookie的应用程序)的标头是相同的,除了实际的主机名。 - nmjk
1
如果浏览器发送了cookie,那么这一定是服务器的问题。也许可以尝试记录或打印服务器从客户端接收到的所有标头,并尝试将$_COOKIE中的所有内容转储到日志中。 - Marc Novakowski

-3

关于 setCookie 函数的php.net说明:

服务器上cookie可用的路径。 如果设置为“/”,则整个域内都可以使用该cookie,如果设置为“/foo/”,则仅可以在/foo/目录及其所有子目录(例如/foo/bar/)中使用该cookie。 默认值是正在设置cookie的当前目录。

cookie可用的域。 要在example.com的所有子域中使cookie可用,则将其设置为“.example.com”。 不需要。 但这样可以兼容更多的浏览器。 将其设置为www.example.com将使cookie仅在www子域中可用。 有关详细信息,请参见 »spec中的尾部匹配。

基本上:您需要检查第4和第5个参数:好吧,您的路径似乎没问题,但域名需要更改:

今天你把cookie阻止了除A域之外的所有其他域,但你希望它能在A和B域都可用。这有点棘手,但是可以解决。 在15秒上获得灵感;-)


我可能错误地解释了您的回复,但根据http://php.net/setcookie文档,我的路径和域应该与我原来的问题中给出的一样正确。如果需要更正,请提供setcookie()函数调用的示例。 - nmjk
1
看起来我可能误解了。当你告诉我你使用两个不同的服务器时,我自动想到了两个不同的主机。但是如果 cookie 只需要在一个主机上可见,那么你的代码似乎是正确的。 :-/ - qualbeen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接