C# 在 ASP.NET 中每个用户只允许一个并发登录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17515716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Allow only one concurrent login per user in ASP.NET
提问by Hiren Dhaduk
Is it possible to allow only one concurrent login per user in ASP.NET web application?
是否可以在 ASP.NET Web 应用程序中每个用户只允许一个并发登录?
I am working on a web application in which I want to make sure that the website allows only one login per user at a time. How to check that the current user already logged in or not?
我正在开发一个 Web 应用程序,我想确保该网站一次只允许每个用户登录一次。如何检查当前用户是否已经登录?
Please suggest proper login method by which we can handle this problem. I think we should use SQL Server session state to handle this problem. What do you suggest?
请建议我们可以处理此问题的正确登录方法。我认为我们应该使用 SQL Server 会话状态来处理这个问题。你有什么建议?
I thought of one solution for it. We can do something like:
我想到了一种解决方案。我们可以这样做:
When the user logs into the system then we insert session id in user column. (We will use database session so that we can get all session related data like isexpired, expiredatetime etc easily).
When the same user tries to login a second time then we will check for that session id column and check that session is already expired or not. If session is not expired then we will not allow user to login.
Update user session ID every time when user logs out.
当用户登录系统时,我们在用户列中插入会话 ID。(我们将使用数据库会话,以便我们可以轻松获取所有与会话相关的数据,如 isexpired、expiredatetime 等)。
当同一用户再次尝试登录时,我们将检查该会话 ID 列并检查该会话是否已过期。如果会话没有过期,那么我们将不允许用户登录。
每次用户注销时更新用户会话 ID。
Please suggest whether this is the proper way or not.
请建议这是否是正确的方法。
采纳答案by Mike Marks
Please refer to:
请参阅:
当同一个用户 ID 尝试在多个设备上登录时,如何终止其他设备上的会话?
Out of the box, .NET does not support this. .NET allows for concurrent log-ins, as I'm sure you're aware.
开箱即用,.NET 不支持此功能。.NET 允许并发登录,我相信您知道。
I had this same exact requirement, and came up with a pretty slick solution, demonstrated in the link above. In a nutshell, my requirement was to only have one user log-in happening at one time. If that same user ID tried to log in elsewhere, then it killed the session for the first log-in by checking for an existing log-in under a different Session ID (this enabled the user ID to be logged in from multiple instances of their web browser on their computer [same Session ID], which is common, but not from a different computer [different Session ID] (possibly due to someone that stole their credentials, for example)). Through modification of the code you could probably change the behavior of this - i.e., prevent the second log-in attempt instead of killing the first log-in that's already active and in use.
我有同样的确切要求,并提出了一个非常巧妙的解决方案,在上面的链接中进行了演示。简而言之,我的要求是一次只有一个用户登录。如果同一个用户 ID 试图在别处登录,那么它会通过检查不同会话 ID 下的现有登录来终止第一次登录的会话(这使得用户 ID 可以从其多个实例登录)。他们计算机上的网络浏览器 [相同的会话 ID],这是常见的,但不是来自不同的计算机 [不同的会话 ID](例如,可能是由于有人窃取了他们的凭据))。通过修改代码,您可能会更改此行为 - 即,防止第二次登录尝试,而不是终止已经处于活动状态且正在使用中的第一个登录。
Of course, it may not fit 100% to what you're needing, so feel free to modify it to fit your needs.
当然,它可能无法 100% 满足您的需求,因此请随时对其进行修改以满足您的需求。
回答by Tombala
You can create a cache entry per user and store their session ID in it. Session ID will be unique per browser session. In your login page, you can create that cache entry when they successfully login:
您可以为每个用户创建一个缓存条目并将他们的会话 ID 存储在其中。每个浏览器会话的会话 ID 将是唯一的。在您的登录页面中,您可以在他们成功登录时创建该缓存条目:
if(Cache.ContainsKey["Login_" + username])
// Handle "Another session exists" case here
else
Cache.Add("Login_" + username, this.Session.SessionID);
(Code typed in textbox without syntax check. Assume "pseudo-code".)
(在没有语法检查的情况下在文本框中键入的代码。假设为“伪代码”。)
In global.asax you can then hook into the Session_End and expire that cache entry of the user. See thisfor the global.asax events.
在 global.asax 中,您可以连接到 Session_End 并使用户的缓存条目过期。有关global.asax 事件,请参阅此内容。
if(Cache.ContainsKey["Login_" + username])
Cache.Remove("Login_" + username);
回答by Aristos
The login credentials are stored on the cookie, so to know if the user is logged in you need to keep this informations on server, prefered on a database because the database can be the only common place among web garden or web farm.
登录凭据存储在 cookie 中,因此要知道用户是否已登录,您需要将此信息保存在服务器上,最好保存在数据库中,因为数据库可能是网络花园或网络农场中唯一常见的地方。
What you can keep, is on a table, that the user Ais logged in or not, flag it that is logged out, maybe last user interaction to have a timeout, etc...
您可以保留的内容是在桌子上,是否user A已登录,将其标记为已注销,可能是最后一次用户交互超时等...
So let say that the User A, is logged in, then you open a flag on the database for that user, that is now logged in, and if is try to logged again, you keep him out. To make this work you need to either say to your users to log out, or to keep a time out, similar to the time out of the credentials.
因此,假设用户 A 已登录,然后您在数据库上为该用户打开一个标志,即现在已登录,如果尝试再次登录,则将他拒之门外。要完成这项工作,您需要告诉您的用户注销或保持超时,类似于凭据超时。
回答by Markus-ipse
You could add a flag column in the user table that indicates that a user is currently logged in.
您可以在用户表中添加一个标志列,指示用户当前已登录。
When a users attempts to log in you check the flag if it's true (that users account is already currently used) then you don't allow the new user to log in, if the flag is false the users is allowed to log in as there account is not being used by anyone else at this time.
当用户尝试登录时,您检查该标志是否为真(该用户帐户当前已被使用)然后您不允许新用户登录,如果该标志为假,则允许用户在那里登录帐户目前未被其他任何人使用。
Be aware though that unless the uses actively logs out, you cannot know when the users moves on to something else (goes to different website or closes the browser, etc.) so you need to set some kind of session timeout that will automatically log out the user if there are no new requests within a specified time period.
请注意,除非用户主动注销,否则您无法知道用户何时转移到其他地方(访问不同的网站或关闭浏览器等),因此您需要设置某种会话超时以自动注销如果在指定时间段内没有新请求,则用户。
This means that if a users closes his/her browser and try to log in on a mobile device for example, he/she will be unable to log in until your specified session timeout runs out, so give the timeout a bit of thought as you don't want the user to get logged out to quickly (if he/she is reading a long page, etc.) and you don't want the users to be unable to log in on another device for hours if he/she forgot to log out before leaving the home.
这意味着,如果用户关闭他/她的浏览器并尝试在例如移动设备上登录,他/她将无法登录,直到您指定的会话超时用完,因此请考虑一下超时不希望用户快速注销(如果他/她正在阅读长页面等)并且您不希望用户在他/她忘记时无法登录另一台设备数小时在离开家之前注销。
回答by Hamza Shafiq
If You are using identity system this link will help you how to single user login on multiple device. Prevent Multiple Logins in Asp.Net IdentityI have tried they work fine in my Asp.net Mvc Project.
如果您使用身份系统,此链接将帮助您如何在多台设备上进行单用户登录。 防止 Asp.Net Identity 中的多次登录我试过它们在我的 Asp.net Mvc 项目中工作正常。
回答by Praveen Yadav
Solution can be this way:
解决方法可以是这样:
Add new column in your login table GuidCode.
Step 1: When logging in check if the GuidCodein database is null.
Step 2: Update GuidCodeby new guid and also store it in the session.
Step 3: If it is not nullthen take guid from the session and compare with database GuidCodevalue.
Step 4: If it is same then allow login:
在您的登录表中添加新列GuidCode。
第 1 步:登录时检查GuidCodein 数据库是否为null.
第 2 步:GuidCode通过新的 guid更新并将其存储在会话中。
第 3 步:如果不是,null则从会话中获取 guid 并与数据库GuidCode值进行比较。
第 4 步:如果相同则允许登录:

