【问题标题】:ASP.net session cookie lost or deletedASP.net 会话 cookie 丢失或删除
【发布时间】:2011-01-13 14:23:35
【问题描述】:

我有一个 ASP.NET 2.0 站点,它在会话中存储用户 ID 以指示他们已登录。在某些情况下,用户似乎没有保持登录状态。我一直在监视 Fiddler 中的流量,以及我发现的一些细节:

  • 在我的旧笔记本电脑上运行 IE7 和项目经理的笔记本电脑运行 IE7 时,该问题 100% 可重复。我当前运行 IE7 的笔记本电脑或任何运行 FF 的笔记本电脑都不会出现此问题。
  • 问题仅出现在生产中,而不是在开发、内部登台或客户端登台中。生产环境是唯一的负载平衡环境,但上面提到的可重复性让我怀疑负载平衡是一个因素。
  • 当设置 Session("ID") = 1 的页面将响应发送回客户端时,我可以在所有情况下看到“Set-Cookie”标头,它正在创建 ASP.Net_Session_Id cookie(它是 HttpOnly )。
  • 对服务器的后续请求将在没有出现问题的机器上发送该 cookie 的标头,但不会在出现问题的机器上发送,因此要么 cookie 被删除,要么“Set-Cookie”标头被忽略。
  • 登录的工作方式如下:www.DomainX.com 上的页面有一个 iframe。该 iframe 的来源是 login.DomainY.com 上的一个页面。 login.DomainY.com 提供的各种页面引导用户完成登录/注册过程。 login.DomainY.com 的最后一步是重定向到 www.DomainX.com 上的页面,包括查询字符串中的用户 ID。 www.DomainX.com 上的这个页面通常将 ID 存储在 session 中,然后运行一些 JS 将顶级文档重定向到新页面,从而将用户带出 iframe。这是一个已经工作了几年的过程,具有 DomainX.com 的几个价值。这里可能不同的一件事是,在这种情况下,JS 只是破坏了 iframe 和一些包含 div 的内容。
  • 我在 Google Analytics cookie 中发现问题发生和未发生的情况之间的另一个区别。 login.DomainY.com/FinalStep.aspx 在 iframe 中重定向到 www.DomainX.com/SaveTheID.aspx 时会有所不同。当问题未发生时,SaveTheID.aspx 请求包括各种 Google Analytics cookie(__utma、__utmz 等)。当问题确实发生时,此请求不包括所有 GA cookie(它缺少 __utma、__utmz 和 __utmb)。
  • 生产环境是 login.DomainY.com 在 SSL 下运行的唯一环境,所以我认为这可能是相关的。但我们暂时将 login.DomainY.com 的临时副本设置为使用 SSL,但没有任何效果。

有什么可能导致这种情况的想法吗?

编辑:生产环境有 www.DomainX.com 和 DomainX.com 的域。还有另一个已知问题是没有为这两个域设置 cookie。这可能是相关的,但在该修复程序进入生产阶段之前我将无法进行测试。

【问题讨论】:

  • 您是否使用 Fiddler 查看过网络流量 - fiddler2.com - 它是查看服务器和浏览器之间发送的流量(包括 cookie 等)的好工具,并且可以配置为解密HTTPS 流量?
  • 是的,我一直在这样做; Fiddler 是我目前所知道的主要信息来源。不过,谢谢。

标签: asp.net internet-explorer session cookies


【解决方案1】:

您需要查看会话状态提供程序,看看它是否可以跨 .net 应用程序的两个服务器/实例工作。例如,如果将它们设置为 inProc,那么您肯定会遇到这个问题,因为每个会话都将与创建它的线程相关联。相反,您希望将其抽象为两台机器都可以访问的 asp.net 状态服务,或者更好的是,您应该使用分布式缓存解决方案,例如 Microsoft Velocity 项目,该解决方案将在两台机器之间分配会话,以防其中一台机器出现故障。

处理此问题的其他一些方法是在负载平衡器上使用粘性会话(不推荐)或转移到无 cookie 会话,这会起作用,但可能会导致代码中的一些问题。

在我们的业务中,我们有一个主服务器和辅助服务器,后面有一个分布式缓存,因此如果一台机器出现故障,另一台机器可以接管。同样的原则也适用于负载平衡,一旦您开始在应用程序池中拥有多台机器甚至多个实例,您将不得不为此编写代码。

如果您将 Velocity 用于会话,请务必确保您选择用于存储会话的缓存是不可驱逐的。

【讨论】:

  • 您能解释一下为什么不建议在负载均衡器上使用粘性会话吗?我一直认为这是一个的主意。
  • 粘性会话会导致请求一直发送到同一台服务器。这意味着如果服务器出现故障,则不会重新路由请求。如果它确实被重新路由,会话将丢失,除非程序为会话状态等建立了冗余。非粘性会话迫使您在应用程序中构建冗余并将其设计为横向扩展并支持节点故障。最后,非粘性会话可让您的路由器更优化地管理流量。请求在节点之间分布更均匀,因为哪​​个框字段请求无关紧要。
【解决方案2】:

我认为 Middletone 是对的,除了:它没有解释为什么不能用 Firefox 重现该问题。负载均衡器是第一嫌疑人;最好通过使除一个应用程序服务器以外的所有应用程序服务器脱机(如果可行,并且在它可以处理负载的时间)来查看它是否有不在场证明,并查看问题是否仍然存在。如果是这样,它不是负载均衡器,您可以开始寻找其他地方。如果不是,那就是负载均衡器。

顺便说一句:粘性会话很糟糕,因为它上面的会话不受冗余保护。此外,负载均衡器不能在某个时间点分配到负载最小的服务器,它只能在会话开始时决定,然后将用户保持在他/她所在的位置。

如果你发现这里遇到了负载平衡器问题,我要做的第一件事是打开会话粘性,然后可能会寻找另一个具有工作生产环境舒缓背景的解决方案。

【讨论】:

    【解决方案3】:

    射击,我一定失去了我的 cookie 以及回复和编辑的能力......

    我确实通过修改我的主机文件以直接指向每个 Web 服务器的 IP,稍微探索了负载平衡器的问题,但这没有任何效果。我认为客户的 IT 人员会拒绝要求关闭负载平衡。

    我们确实有一个单独的状态服务器在运行,它与在同一服务器托管的其他网站上使用了几年的状态服务器相同。不一定没有问题,但没有这样的问题。

    作为一个创可贴,我目前正在测试其他持久性机制...

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2012-08-12
      • 2017-03-16
      • 1970-01-01
      • 2020-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      相关资源
      最近更新 更多