在ASP.NET中,每个用户只允许一次并发登录



在ASP.NET web应用程序中,每个用户是否可以只允许一次并发登录?

我正在开发一个网络应用程序,我想确保该网站每次只允许每个用户登录一次。如何检查当前用户是否已登录?

请建议我们处理这个问题的正确登录方法。我认为我们应该使用SQL Server会话状态来处理这个问题。你有什么建议?

我想了一个解决方案。我们可以做一些类似的事情:

  1. 当用户登录到系统中时,我们在用户列中插入会话id。(我们将使用数据库会话,这样我们就可以轻松地获得所有与会话相关的数据,如isexpired、expiredatetime等)。

  2. 当同一用户尝试第二次登录时,我们将检查该会话id列,并检查会话是否已过期。若会话未过期,则我们将不允许用户登录。

  3. 每次用户注销时更新用户会话ID。

请说明这是否正确。

请参阅:

当同一个用户ID试图在多个设备上登录时,如何终止另一个设备上的会话?

开箱即用,.NET不支持此功能。NET允许并发登录,我相信你已经知道了。

我也有同样的要求,并提出了一个非常巧妙的解决方案,如上面的链接所示。简而言之,我的要求是一次只能有一个用户登录。如果同一用户ID试图在其他地方登录,然后,它通过检查不同会话ID下的现有登录来终止第一次登录的会话(这使得用户ID能够从其计算机上的web浏览器的多个实例[相同会话ID]登录,这是常见的,但不能从不同的计算机[不同会话ID](例如,可能是由于有人窃取了他们的凭据))。通过修改代码,您可能会改变这种行为——即,阻止第二次登录尝试,而不是杀死已经激活并正在使用的第一次登录。

当然,它可能不能100%满足你的需求,所以可以随意修改以满足你的需要。

您可以为每个用户创建一个缓存条目,并将其会话ID存储在其中。每个浏览器会话的会话ID都是唯一的。在您的登录页面中,当他们成功登录时,您可以创建缓存条目:

if(Cache.ContainsKey["Login_" + username])
    // Handle "Another session exists" case here
else
    Cache.Add("Login_" + username, this.Session.SessionID);

(在没有语法检查的文本框中键入的代码。假设为"伪代码"。)

在global.asax中,您可以挂接Session_End并使用户的缓存项过期。有关global.asax事件,请参阅此。

if(Cache.ContainsKey["Login_" + username])
    Cache.Remove("Login_" + username);

您可以在用户表中添加一个标志列,指示用户当前已登录。

当用户尝试登录时,如果该标志为真(该用户帐户当前已被使用),则不允许新用户登录,如果该标记为假,则允许用户登录,因为该帐户此时没有被其他人使用。

请注意,除非用户主动注销,否则您无法知道用户何时转到其他位置(转到不同的网站或关闭浏览器等),因此您需要设置某种会话超时,如果在指定的时间段内没有新请求,则会自动注销用户。

这意味着,例如,如果用户关闭浏览器并尝试登录移动设备,他/她将无法登录,直到您指定的会话超时用完,因此,考虑一下超时时间,因为你不希望用户快速注销(如果他/她正在阅读一个长页面等),也不希望用户在离开家之前忘记注销,在数小时内无法登录另一台设备。

登录凭据存储在cookie上,因此要知道用户是否登录,您需要将这些信息保存在服务器上,最好保存在数据库上,因为数据库可能是网络花园或网络农场中唯一常见的地方。

你可以在一张表上记录user A是否登录,标记它已注销,可能是最后一次用户交互超时,等等

假设用户A已经登录,那么你在数据库上为该用户打开一个标志,该用户现在已经登录,如果他试图再次登录,你就把他拒之门外。要做到这一点,你需要对用户说注销,或者保留一个超时时间,类似于凭据的超时时间。

如果您使用的是身份系统,此链接将帮助您如何在多个设备上进行单用户登录。防止Asp.Net标识中的多次登录我在我的Asp.net Mvc项目中尝试过它们的良好工作。

解决方案可以是这样的:

在登录表GuidCode中添加新列
步骤1:登录时,检查数据库中的GuidCode是否为null
步骤2:使用新的guid更新GuidCode,并将其存储在会话中
步骤3:如果不是null,则从会话中获取guid并与数据库GuidCode值进行比较
步骤4:如果相同,则允许登录:

最新更新