在ASP.Net中,我能否通过会话ID查找另一个会话是否存在或有效?

6

有没有办法在现有请求的上下文中确定会话 ID 是否有效? 如果我收到一个会话 ID,而且我当前正在由 HTTP 请求启动的另一个会话中,并且我在页面上或某个类中,那么我可以验证该会话 ID 是否有效、是否存在并且尚未被放弃吗?

原因是,我们需要锁定项目中页面上的用户登录过程,以便任何用户只能登录一次。 我想在用户表中添加会话 ID 列来实现此目的,如果为 null,则已注销,登录时设置,注销时清除或在 global.asax 的 Session_End 上。 但是,如果某个会话由于某种原因被放弃而没有清除它,我需要能够再次将其登录,如果这种情况下他们登录并发现该列中有会话 ID,则应检查该会话 ID 是否仍处于活动状态和有效状态,如果不是,则将其重置为新会话 ID 并允许他们登录。

谢谢


您需要永久维护他们的会话吗?这意味着ASP .NET最终将放弃过期的会话。但从用户的角度来看,应用程序状态是否应始终保持不变? - Yuck
我们没有使用基于cookie的身份验证,而是使用活动会话并将用户对象存储在其中。我们有一个滑动的30分钟超时时间,需要用户重新登录。当会话超时时,他们将被“注销”,并且必须再次登录。 - user358089
4个回答

2

上面的评论英语不太好,但是想法正确。如果您在会话状态中使用了SQL服务器,则我认为它将会话ID存储为列。您可以直接检查它。 - Rocklan

1

你还有另一个选择,可以使用WeakReferences:

  • 在应用程序级别存储一个Dictionary<youruseridtype,WeakReference>,作为Application["mySessionDictionnary"]
  • 在启动会话时,将用户ID和对Session对象本身的WeakReference存储在字典中
  • 当用户想要登录时,检查字典中是否存在他或她的ID。如果存在指向Session对象的非空WeakReference,则可以Abandon()此现有的Session对象,确保每个用户最多只有一个活动会话。

WeakReference确保您不会遭受内存泄漏。

NB:这仅适用于inProc会话管理。由于字典无法在应用程序重新启动后继续存在,因此会话也应该是如此。

希望你已经找到了解决问题的正确答案;-)


1

我能想到的唯一方法是按照Neperz所说的,使用SQLServer会话提供程序将您的会话存储在数据库中,这意味着您可以使用SQL查询来查看可用内容。

但是需要考虑一些注意事项:

  1. 我认为存储在会话数据库表中的会话ID与您可以从代码中访问的会话ID不完全相同。我不太记得我在哪里读到这个问题,但我认为当我正在执行类似于监视所有活动会话的操作时,我遇到了这个问题。
  2. 如果使用SQLServer会话提供程序,则全局Session_End事件永远不会触发。
  3. 除非您在代码中明确使用Session.Abandon()来结束会话(例如,当用户注销时),否则您的会话可能会挂起,直到SQL代理作业清理任何过期的会话。这意味着,如果有人只是关闭了他们的浏览器窗口,那么他们的会话仍然会显示为“活动”,这可能会使您的实现变得复杂。

0

没有直接验证SessionId的方法。以下是选项:

  • 您可以实现自己的会话状态提供程序(或者可能仅需要ID管理器)来公开访问该信息(http://msdn.microsoft.com/en-us/library/aa479024.aspx)。
  • 尝试欺骗,通过设置基于您认为当前用户应该拥有的ID的会话ID cookie并重新呈现页面。第二个请求,您将能够看到该ID是否对应于有效状态,并在需要时重新登录。

注意:我不会使用session Id来进行此操作,因为您将依赖于实现细节。也许简单地拒绝不像此用户最新的会话的会话会起作用。在Session["someName"]和用户DB中保存“我的当前会话名称”属性就足以拒绝呈现旧会话。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接