是否可以在Asp.Net Web应用程序中仅允许每个用户进行一次并发登录?
我正在开发一个Web应用程序,我希望确保该网站每个用户一次只能登录一次。如何检查当前用户是否已登录。
建议正确的登录方法,以便我们处理此问题。我认为我们应该使用sql server session state来处理这个问题。你的建议是什么?
我想到了一个解决方案。我不知道它是否合适。我们可以这样做:
当用户登录系统时,我们会在用户列中插入会话ID。 (我们将使用数据库会话,以便我们可以轻松获取所有与会话相关的数据,如isexpired,expiredatetime等。
当同一用户尝试第二次登录时,我们将检查该会话ID列并检查该会话是否已过期。如果会话未过期,我们将不允许用户登录。
每次用户注销时都更新用户会话ID。
请以正确的方式提出建议。
答案 0 :(得分:9)
请参阅:
开箱即用,.NET不支持此功能。 .NET允许并发登录,因为我相信你已经知道了。
我有同样的要求,并提出了一个非常光滑的解决方案,在上面的链接中演示。简而言之,我的要求是一次只能有一个用户登录。如果相同的用户ID尝试在其他地方登录,则它会通过检查不同会话ID下的现有登录来终止第一次登录的会话(这使得用户ID可以从其多个实例登录)网络浏览器在他们的计算机上[相同的会话ID],这是常见的,但不是来自不同的计算机[不同的会话ID](例如,可能是由于某人窃取了他们的凭据))。通过修改代码,你可以改变它的行为 - 即,防止第二次登录尝试,而不是杀死已经激活和使用的第一次登录。
当然,它可能不适合您所需要的100%,因此可以随意修改它以满足您的需求。
答案 1 :(得分:5)
您可以为每个用户创建一个缓存条目,并将其会话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并使该用户的缓存条目到期。 See this用于global.asax事件。
if(Cache.ContainsKey["Login_" + username])
Cache.Remove("Login_" + username);
答案 2 :(得分:2)
您可以在用户表中添加一个标志列,指示用户当前已登录。
当用户尝试登录时,检查标志是否为真(用户帐户当前已使用),则不允许新用户登录,如果标志为false,则允许用户登录因为此时其他任何人都没有使用过帐户。
请注意,除非使用主动注销,否则您无法知道用户何时转移到其他位置(转到不同的网站或关闭浏览器等),因此您需要设置某种会话超时如果在指定时间段内没有新请求,则自动注销用户。
这意味着如果用户关闭了他/她的浏览器并尝试登录移动设备,他/她将无法登录,直到您指定的会话超时用完为止,因此请暂停一下我们认为你不希望用户快速登出(如果他/她正在阅读长篇页面等)并且你不希望用户在几个小时内无法登录其他设备/她在离开家之前忘了退出。
答案 3 :(得分:1)
登录凭据存储在cookie中,因此知道用户是否已登录,您需要在服务器上保留此信息,因为数据库可能是唯一的常见位置在网络花园或网络农场中。
你可以保留,在桌面上,user A
是否已登录,标记已登出,可能是最后一次用户交互以超时等等...
因此,假设用户A已登录,然后您在该数据库的数据库上打开一个标志,该标志现在已登录,如果尝试再次登录,则会阻止他。 要完成这项工作,您需要向用户说出注销,或者保持超时,类似于凭据的超时时间。
答案 4 :(得分:1)
如果您使用的是身份系统,此链接将帮助您在多个设备上单独登录用户。 Prevent Multiple Logins in Asp.Net Identity 我试过他们在我的Asp.net Mvc项目中工作正常。
答案 5 :(得分:0)
解决方案可以是这种方式:
在登录表GuidCode
中添加新列。
步骤1 :登录时,检查数据库中的GuidCode
是否为null
。
第2步:通过新的guid更新GuidCode
并将其存储在会话中。
步骤3 :如果不是null
,则从会话中获取guid并与数据库GuidCode
的值进行比较。
步骤4 :如果相同,则允许登录: