如何解决ASP.NET、VB.NET中的会话问题?

3
如何在ASP.NET和VB.NET中解决这个会话问题?
以下是要求:
当授权用户登录系统时,该用户不允许从另一台计算机或不同的浏览器登录,除非该用户正在使用此浏览器。
我们采取了以下措施:我们在mst_vendor表中将“Is_Loggedin”作为数据类型为“bit”的列。当用户登录时,我们设置标志Is_Loggedin为“1”,每次有人尝试使用此帐户登录时,系统都会显示错误“用户已经登录”。当用户登出时,它变为“0”,因为登出过程会在用户单击登出按钮后立即调用。
问题场景:
1. 当用户关闭浏览器时,标志保持不变,即“1”。 2. 当电源关闭时,它仍然保持为“1”。 3. 如果会话超时达到预定值,则仍然保持不变。 4. 还可能存在其他情况。
是否有任何方法可以使用应用程序对象存储用户登录状态的内部标志?
这可能会提高系统的效率,并消除上述问题场景。

1
如果您想要VB.NET的答案,为什么要加上C#C++标签呢? - Hans Kesting
5个回答

4

我只有看到才会相信,服务器怎么可能知道浏览器何时关闭? - m.edmondson
1
它不会意识到浏览器何时关闭,但会话最终会超时并引发Session_End事件。 - StuperUser
3
注意:Session_End 只会针对 'InProc' 会话触发。 - Hans Kesting

2

在位旁边存储一个日期时间,并在用户请求页面时每次更新它。

当具有相同凭据且位为“1”的新用户出现时,您可以检查日期时间,如果已经过了一段时间,则可以确定用户不再存在。因此,让登录继续进行。


0
你可以在脚本中保持一个脉冲,当脉冲超时时,就认为用户已经完成了该会话。
这样做的好处是,你可以区分用户在网站上闲置和用户离开网站的情况。

0

是的,脚本是个好主意。只需将会话超时设置为5分钟而不是20分钟,然后在global.asax文件中编写一个方法到session.end,以相应地更新数据库。


如果发生停电,这段代码就不会被执行。 - m.edmondson
为什么不行呢?如果客户端停电,会话将像正常情况下超时。 - StuperUser
1
我认为他们的意思是总体而言,即包括他们整个公司,包括服务器。 - m.edmondson
事实上,服务器停电将意味着Session_End不会像平常一样触发。我不确定会发生什么。恢复计划应包括重置这些标志。 - StuperUser

0

从非常高层次的角度来看,这里是你可以做的事情

使用具有滑动过期时间的缓存。
每次用户尝试登录时,检查以其用户名为键的缓存。如果缓存中存在条目,则可以说明用户已经登录,并拒绝登录。
如果未找到该键,则允许登录并在缓存中创建一个新键作为用户名,并设置滑动过期时间。(应仔细选择此时间段,因为这将是用户在关闭浏览器并尝试重新登录后不会被锁定的时间。)
在全局的 Application_PreRequestHandlerExecute 处理程序中检查用户当前是否处于活动状态(可以使用会话进行此操作),并重置用户的滑动过期时间。这样,随着每个页面请求,缓存过期时间都将被重置。
如果用户关闭浏览器并离开,则缓存将在设置的一段时间后过期,并释放用户重新登录。
如果用户在缓存过期之前再次尝试登录,则必须等待一段时间让缓存过期。
如果用户正确注销,则可以在注销事件上删除缓存条目,以便用户无需等待即可重新登录。

滑动过期超时时间可以与会话超时同步,以模拟应用程序的实际会话超时。

采用这种方法,您还可以节省大量数据库往返以更新/检查用户状态,并且无论托管环境或会话模式如何,都可以正常工作。


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