【问题标题】:How does ASP.NET (or any web framework) implement persistent session state?ASP.NET(或任何 Web 框架)如何实现持久会话状态?
【发布时间】:2010-01-07 07:58:50
【问题描述】:

由于各种原因,我厌倦了 ASP.NET 会话状态,我正在尝试自己做(即将出现的另一个问题与我厌倦的原因以及我自己做这件事是否可行有关,但现在让我们假设它是)。

抛开安全问题不谈,跟踪会话似乎只涉及存储一个带有 guid 的 cookie 并将该 guid 与数据库中的一个小“会话”表相关联,该表以 guid 为键并包含少量字段对于链接到注册用户的会话,跟踪超时并链接到用户表中的主键。

但是,如果用户的浏览器未设置为接受 cookie,我对 cookie 的一个细节感到困惑。在我看来,每次用户访问任何启用了会话状态的页面时,ASP.NET 都必须确定浏览器是否支持 cookie。如果已经有随请求发送的会话 cookie,则显然它知道 cookie 已被接受。

如果没有,它似乎需要检查,据我了解,这涉及尝试写入 cookie 并重定向到尝试读取 cookie 的页面。因此,当关闭了 cookie 的用户访问网站的多个页面时,似乎 ASP.NET

(a) 必须对用户访问的每个页面进行此往返测试,或者

(b) 必须假设浏览器接受 cookie 并在每个页面上为用户创建一个带有(临时)会话 id 的记录——如果会话状态应该是持久的,它似乎必须写入初始状态每个页面上数据库的会话 ID。

但是 (a) 听起来很疯狂, (b) 听起来也很疯狂,因为我们会很快为所有这些单页会话累积会话 ID。因此,我认为必须有一些其他技巧/启发式方法用于知道何时进行往返测试和/或何时实际为会话创建记录。

我的困惑是错的吗?

(要清楚,我不是在谈论在 ASP.NET 的可插拔会话状态系统中实现自定义存储解决方案。我说的是完全跳过 ASP.NET 的会话状态系统。我的问题是更详细的版本这个:Implementing own Session Management in ASP.NET.)

【问题讨论】:

  • 读了几次之后,我想我知道你想表达什么了。是的,(a)和(b)听起来确实很疯狂。希望有人能启发我们。

标签: asp.net session session-state


【解决方案1】:

会话行为是通过 web.config 中的 sessionState 元素设置的。在 sessionState 元素中,HttpCookieMode 可以设置为UseUri, UseCookies, AutoDetect, UseDeviceProfile 之一。

UseUri 和 UseCookies 明确地告诉 ASP.NET 如何处理存储会话标识符。如果使用 UseDeviceProfile,则行为取决于用户代理是否支持 cookie(而不是它们是否启用)。

AutoDetect 是您感兴趣的有趣案例。Understand How the ASP.NET Cookieless Feature Works 中解释了 ASP.NET 如何处理自动检测。在那篇文章中,您将看到他们进行了 5 种不同的检查。正如您所提到的,其中一项检查是设置 cookie 并执行重定向以查看 cookie 是否存在。如果 cookie 存在,则浏览器支持 cookie 并设置 sessionID cookie。但是,这并不是对每个请求都进行的,因为他们在进行重定向之前所做的另一项检查是检查是否存在任何 cookie。因为在初始 set-cookie 和重定向之后 sessionID cookie 将被设置,那么 cookie 的存在让 ASP.NET 知道 cookie 是受支持的,并且不需要进一步的 set-cookie 和重定向。

【讨论】:

  • 是的,我认为该链接中的算法主要是我最初问题的答案。关键似乎是它避免在每个页面上进行往返检查,因为在第一次往返失败后,它会修改 URL,从那时起,修改后的 URL 就是不支持 cookie 并且不需要更多检查的标志.然而,似乎还有一个基本的未解决问题。如果您将模式设置为 UseCookies(而不是 AutoDetect),那么它是否会在每个页面上进行往返(因为不允许 (?) 修改 URL)?
【解决方案2】:

嗯,cookie 是一种标准的 Web 身份验证机制。你有什么理由不想使用它们吗?你确定你不是想发明一个没有问题的问题吗?

我所知道的大多数严肃网站都要求浏览器接受 cookie 才能对用户进行身份验证。可以肯定地假设每个现代浏览器都支持它们。

有一篇关于cookieless ASP.NET 的有趣文章值得一读。

编辑:

@o.k.w:默认情况下,会话状态由 ASP.NET 进程内保存(读取:在内存中)。除非配置明确告知将会话存储在数据库中(开箱即用地支持 SQL Server),否则这不会导致数据库命中。陈旧的会话状态将从进程内存储中清除。不幸的是,使用默认的 ASP.NET 设置,每个无 cookie 请求都会导致创建一个新会话。

以下是可用会话存储选项的详细比较:http://msdn.microsoft.com/en-us/library/ms178586.aspx

【讨论】:

  • @Mercin,我不认为这是 OP 关心的问题。问题之一是,如果请求不包含已知会话(或会话 ID),Web 服务器是否会创建新会话?如果是这样,如果客户端不支持 cookie,这将“浪费”服务器资源。然后服务器会知道它不需要“关心”这个特定的无 cookie 客户端的会话 cookie 吗?如果有,怎么做?
  • 感谢您提供此信息,但我认为它不能回答我的问题。
  • @M Katz:我以为我回答了你的问题。请你重新表述你的问题好吗?我不确定你现在在问什么。
  • 谢谢。是的,我想你几乎回答了它,但我关注的是它如何具体地知道你是处于 cookie 还是无 cookie 的情况,以及它是如何做到这一点的,而无需为页面创建所有这些临时会话记录永远不会加入会话。我知道无 cookie 会话,但我试图了解您的目标是否是使用 cookie,但浏览器不支持它们,如何避免服务器因此受到伤害。
  • 配置为使用 cookie 作为会话 id 的服务器没有 100% 可靠的方法来判断没有 cookie 的请求是 new 会话还是 i>cookieless 请求。服务器将向浏览器发送会话 cookie,因为它认为这是一个新会话。由于浏览器不支持 cookie,它不会将其发回,并且每个后续请求都会被服务器视为 新会话 ...正如 RickNZ 所说,> 99% 的真实用户支持 cookie,因此您不必担心剩余的
猜你喜欢
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多