据我了解,Session 对象用于存储每个 session 的数据。我做了以下实验:
- 打开浏览器并访问一个aspx页面A,该页面将一些数据保存到Session对象中。
- 保持浏览器打开并打开另一个选项卡以访问显示 session 数据的 aspx 页面 B。它显示的内容与我在步骤 1 中存储的内容一样。
- 我关闭浏览器并重新访问页面 B,存储的数据消失了。
从 3 开始,服务器端似乎以某种方式检测到我(客户端)已终止 session 。但正如我用 Fiddler 检查的那样,当我在步骤 3 中关闭浏览器时,没有任何位发送到服务器。
那么 ASP.NET 应用程序怎么可能知道我的第 3 步请求是针对新 session 的?
session 是如何定义的?不同的选项卡是否始终属于同一个 session ?
添加1
虽然页面A和页面B都可以显示 session 数据,但是它们显示的 session ID是不同的。为什么?
正确
页面A和页面B中的 session id相同。我没有使用 InPrivate 浏览。
添加2
确实有一个用于 session ID 的 Cookie:
ASP.NET_SessionId=lmswljirqdjxdfq3mvmbwroy; path=/; domain=localhost; HttpOnly
它是在响应 POST 请求时设置的。
所以我做了另一个实验,我关闭了浏览器(Fire Fox),正如预期的那样,Cookie 不再存在。我手动创建 cookie,希望“伪造的 Cookie 可以恢复旧 session 。”,但 Fiddler 表明手动 cookie 根本没有发送。
fiddler 说:
This request did not send any cookie data.
那么是否有可能伪造 cookie 并恢复之前的 session ?
session 在服务器上存活多久?
最佳答案
当服务器启动新 session 时,它会为该 session 生成一个新标识符。 session 数据存储在 session 提供程序中的此标识符/ key 下(可以存储在内存中、SQL Server 中或完全其他位置,具体取决于您的配置 - 通常在 web.config 中配置)。
同时,服务器会向您的浏览器发送一个 cookie(至少在默认设置中)。此 cookie 包含您的 session 的标识符。这就是服务器如何将您的请求与特定 session 相关联:在每个请求中,您的浏览器都会发送 session cookie。服务器从 cookie 中检索标识符并使用该标识符查找您的 session 数据。
session cookie是非持久性的,这意味着当浏览器关闭时cookie将被删除。这就是为什么看起来
session 已被删除: session 数据仍然存在于服务器上,但由于 session cookie 已被删除,浏览器不会发送 session cookie,因此服务器会认为这是一个新 session 的开始,创建一个新的 session 标识符等。因此,服务器并不真正知道 session 何时结束,它只知道 session 何时开始。这就是为什么在默认的 SQL Server 支持的设置中,计划作业将清除不活动的 session - 否则 session 数据将永远保留在数据库中。
有关 session 、使用不带 cookie 的 session 、 session 配置、提供程序等的更多信息,请参阅 MSDN .
至于 session 是否在浏览器选项卡之间共享:这实际上取决于 cookie 是否在选项卡之间共享。我认为 Cookie 是在所有主要浏览器中的选项卡之间共享的,如果不是,我认为会相当困惑,但没有什么可以阻止某人创建一个不跨选项卡共享 Cookie 的浏览器。
编辑 1
如果您删除 session cookie,理论上您可以通过重新创建 cookie 来重新创建 session 。这本身并不是一个安全问题,因为您正在重新创建您已经有权访问的数据。但是,如果其他人重新创建您的 session cookie,这将是一个安全问题。如果你想研究这个问题,你可以谷歌搜索“ASP.NET session hijacking”。
编辑2
session 基本上存在于服务器上,直到有东西清除它。因此, session 的生命周期取决于您存储它的位置。如果将其存储在内存中,则当应用程序被回收时(可能是因为您在 IIS 中回收应用程序或服务器重新启动), session 将被删除。如果你将它存储在 SQL Server 中, session 数据将一直存在,直到作业将其删除,因为它已经有一段时间没有被访问了(抱歉,我不记得详细信息,但你可能可以通过 google 搜索它们)。如果您将 session 数据存储在 Azure 表存储中,它们可能永远不会被清除。
注意
ASP.NET session 状态的两个重要细节经常被忽视:
- 当 session 存储在进程外部(例如,在 SQL Server 中)时,您要存储的数据必须是可序列化的。
- 为了防止访问 session 数据时出现争用情况,访问 session 的请求将被序列化,也就是说,它们将不会同时执行。
更多详细信息可以在 the MSDN article "Underpinnings of the Session State Implementation in ASP.NET" 中找到。
关于asp.net - ASP.NET 服务器如何知道 session 何时终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24782241/