【问题标题】:IE10 sharing cookies across subdomains by defaultIE10默认跨子域共享cookie
【发布时间】:2013-02-13 11:39:45
【问题描述】:

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

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

  • 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 适用于哪个域之外,是否有任何解决方法?

【问题讨论】:

  • 我遇到了 IE10 和 cookie 的问题。不知道你的问题是不是一样。有关我的问题的更多信息,请参见此处:stackoverflow.com/questions/15856886/…
  • 这种行为在 IE8 和 IE9 中也存在。

标签: php internet-explorer web-applications cookies


【解决方案1】:

我刚刚遇到这个问题。

以下是探索此错误/问题的人的链接: 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 上设置多个属性,包括 cookie 应关联的域。我将此属性留给 .net 定义/未定义。当 Chrome 从每个站点收到 cookie 时,它​​会将 cookie 的域显示为明确来自浏览器地址栏中列出的域。在 IE 中,情况并非如此。 IE 将来自http://sites.com 的 cookie 视为定义为“.sites.com”,根据 RFC 的 cookie 这意味着它可以从所有子域访问。

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

据我所知,在.net 中,cookie 通常是通过键名而不是索引来访问的。因此,当服务器端代码尝试访问名为“ShoppingCart”的键的值时,它将获取第一个设置 cookie 值的站点的值 - 这里将是 http://sites.com。

总而言之 - 当您的子域都共享相同的 cookie 键名时,不要使用非 www 域,因为虽然 Chrome/Firefox 会按预期处理域关联,但 IE 会导致错误行为。

编辑--

为了向阅读本文的人澄清一下,我使用 IE10 来探索这个问题。

【讨论】:

    【解决方案2】:

    如果您在一个域上有多个 PHP 站点,那么解决此问题的超级简单方法。

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

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

    session_name('AppSession');
    session_start();
    

    简单。

    【讨论】:

    • 是的,谢谢你,这对我完全有用。我有 example.com 和 webapp.example.com,并且来自 example.com 的 cookie 在 IE 中发生冲突,所以我无法登录 webapp.example.com。这为我修复了它,我只是将域名放入会话名称中。 $sesName = (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']); $sesName = str_replace('.', '', $sesName); $sesName = str_replace('-', '', $sesName); $sesName = str_replace(':', '', $sesName); session_name($sesName);
    【解决方案3】:
    【解决方案4】:

    我在 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']);
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-27
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 2018-05-20
      • 2012-08-30
      相关资源
      最近更新 更多