IE10默认情况下跨子域共享cookie

时间:2013-02-27 15:30:54

标签: php internet-explorer web-applications cookies

IE10似乎与其他主流浏览器(IE8,IE9,Firefox,Chrome,Safari)处理不同的cookie和子域名。

我们广泛使用子域用于测试环境,例如:

  • user1.devel.example.com
  • user2.devel.example.com
  • qa.example.com

我们的生产环境居于首位,例如example.com(技术上也是www.example.com)。

我们天真地使用php setcookie($name, $value, $expires)函数(没有指定显式路径或域)来设置cookie,然后通过为值分配空字符串来清除cookie(当用户注销时)。这一直很好,每个独特的子域都使用自己的cookie。

IE10现在“共享”在TLD中设置的所有子域名的cookie。我们观察到的初始症状是没有人可以退出子域名。我们观察了一些事情:

  • 即使它共享该值,也没有子域能够清除cookie。
  • 当TLD清除cookie时,它也会立即从所有子域中删除。

有没有其他人观察到IE10如何存储/应用相对于子域名的cookie的类似行为?是否有任何解决方法,除了明确说明在发送初始Set-Cookie标头时cookie适用于哪个域?

4 个答案:

答案 0 :(得分:15)

我刚遇到这个问题。

这是指向探索此错误/问题的人的链接: Cookies with and without the Domain Specified (browser inconsistency)

这也可能与此有关: Cookie set for subdomain, but IE Developer Tools show cookie at root domain. What am I missing?

我的结论是,当从非www根域(http://sites.com)设置cookie时,在IE中,这被视为所有子域的通配符cookie。 Chrome和Firefox不会显示此行为 - 它们将非www根域中的Cookie集关联为仅与该根关联。

我使用.net webforms,IIS和我的hosts文件编写了示例站点。我有3个网站: a.site.com,b.site.com和site.com。他们都提供了完全相同名称的cookie。我们称之为“ShoppingCart”。

您可以在Cookie上设置多个属性,包括Cookie应与之关联的域。我将此属性保留为.net定义/未定义。当Chrome从每个网站收到Cookie时,它会将Cookie的域显示为明确来自浏览器地址栏中列出的域。在IE中,情况并非如此。 IE将http://sites.com中的cookie视为“.sites.com”,根据RFC的RFC,这意味着可以从所有子域访问该cookie。

同样在IE中,如果使用相同的名称设置多个cookie,IE会按照设置顺序将它们返回给服务器。因此,如果我首先访问http://sites.com然后访问http://a.sites.com然后刷新,则IE会将http://sites.com中的Cookie视为有效的Cookie,以便将http://a.sites.com请求发送给服务器与http://a.sites.com的Cookie一起发送,但http://sites.com的Cookie是列表中的第一个。

在.net中,从我看到的情况来看,cookie通常是通过keyname访问的,而不是通过索引访问的。因此,当服务器端代码尝试访问名为“ShoppingCart”的密钥的值时,它将获取设置cookie值的第一个站点的值 - 此处为http://sites.com

总而言之 - 当您拥有共享相同Cookie密钥名称的子域名时,请不要使用非www域名,因为当Chrome / Firefox按预期处理域关联时,IE会导致错误行为。

编辑 -

为了澄清任何阅读此内容的人,我使用IE10来探讨这个问题。

答案 1 :(得分:3)

如果域上有多个PHP站点,则可以通过超级简便的方法解决此问题。

例如 - 如果你在root(example.com)上有Wordpress并且你在子域(a.example.com)上有一个自定义PHP应用程序,那么在你的app或Wordpress中你需要设置一个不同的SessionName。

在session_start()之前添加session_name(),它应该为会话提供两个单独的名称,因此不会发生冲突。

session_name('AppSession');
session_start();

易。

答案 2 :(得分:1)

答案 3 :(得分:0)

我在IE 11.0.9600中遇到与php会话cookie相同的问题:Internet Explorer正在向其所有子域发送根域cookie。为了解决这个问题,我将域名存储在会话变量中:

$_SESSION['URL'] = str_replace('www.', '', $_SERVER['HTTP_HOST']);

然后对于每个请求,我检查会话变量:

if ( str_replace('www.', '', $_SERVER['HTTP_HOST']) !=  $_SESSION['URL']) {
  session_regenerate_id(true);
  $_SESSION = array();
  $_SESSION['URL'] = str_replace('www.', '', $_SERVER['HTTP_HOST']);
}

然后,当我们从根域移动到子域时,我们将不会“进入”同一会话。