请指导如何使用用户ID一次防止多个用户登录?
我搜索了互联网并找到了一些方法,但不知怎的,他们在这些情况下不起作用:
请以某种方式建议我。
感谢
haansi
答案 0 :(得分:18)
我们按照以下方针为此实施了一个系统:
我们选择了基类选项,因为我们有两个级别的身份验证:
几乎所有系统都会找到主要问题:
InProc
个会话,则SessionEnd事件永远不会触发,如果您的服务器崩溃,则不会调用该事件等。您可以通过我的解决方案找到的问题是:
回复评论
回应您的具体问题:
最基本的,这不会阻止用户共享他们的登录,但会导致他们烦恼,迫使他们继续登录。如果需要,可以为登录过程添加延迟 - 所以如果不同会话ID尝试在会话超时(默认为20分钟)或其他时间(例如,基于用户在页面上花费的平均时间)登录站点,然后拒绝登录尝试。
答案 1 :(得分:11)
可能有几种可能性。快速回复是:
在数据库中维护一个标志;每次登录/退出时都会更新标志。例如,如果标志已经为真,则每次认证请求都可以拒绝登录请求。
或者,您可以在Application
对象中维护用户列表,并使用.Contains
查看它是否已存在。
<强> - 编辑 - 强>
让我们尝试数据库标志选项;并假设您有一个名为StillLoggedIn(User)
的方法来更新日期/时间和标记。
因此,当用户登录时:
对于后续请求,应用会调用StillLoggedIn(User)
;
准备一个可以不时浏览数据库的Windows服务(如果你有10000个用户,可以说5分钟后)。如果 currentTime减去lastUsedTime大于,比如5分钟,该服务会将数据库日期/时间与当前日期/时间进行比较,并将标记标记为0
。
它可以是数据库和Windows服务之外的任何东西。
答案 2 :(得分:2)
这就是我的方式。
用户登录后,检查来自DB的flag和sessionID,如果发现使用相同的帐户和不同的sessionID登录(比较新生成的当前sessionID和来自DB的sessionID),请提醒用户“系统检测到您没有从您上次登录时,点击&lt;“确定”&gt;退出上次登录并创建新会话。“ 如果没问题,只需将旧的SessionId替换为DB中的当前SessionID。
还有一件事是在每个页面中检查来自DB的当前sessionID和sessionID,如果不相同,则注销并重定向到登录页面。
无论用户没有正确注销或只是关闭浏览器,用户都有机会退出自己,无需等到IIS会话结束。 它将阻止同时使用同一帐户进行多次登录。
希望这有帮助,谢谢...
答案 3 :(得分:2)
我们所做的是使用会话状态和应用程序状态的组合来防止重复登录。
当用户登录时,他从user.net数据库中检索到userId,并将其作为唯一对象保存在Application状态中。
由于应用程序状态对应用程序是全局的而不是特定于用户会话,因此我们可以检查userId是否已保存在应用程序状态中。如果已经保存,我们可以通知用户并停止登录。 当会话到期时(在Global.asax文件中的Session_End上),可以从Application状态中删除该特定用户的Application状态对象,以便他可以在会话过期后再次登录。
这是代码: 在Login.aspx.cs中:
protected void OnLoggingIn(object sender, LoginCancelEventArgs e)
{
// Accesses the database to get the logged-in user.
MembershipUser userInfo = Membership.GetUser(LoginUser.UserName);
UserMan.UserID = userInfo.ProviderUserKey.ToString();
if (Application[UserMan.UserID] != null)
{
if (Convert.ToString(Application[UserMan.UserID]) == UserMan.UserID)
{
e.Cancel = true;
}
else
{
// Save the user id retrieved from membership database to application state.
Application[UserMan.UserID] = UserMan.UserID;
}
}
else
{
Application[UserMan.UserID] = UserMan.UserID;
}
}
在Global.asax中:
void Session_End(object sender, EventArgs e)
{
// Code that runs when a session ends.
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
if (Application[UserMan.UserID] != null)
{
if (Convert.ToString(Application[UserMan.UserID]) == UserMan.UserID)
{
Application.Contents.Remove(UserMan.UserID);
}
}
}
虽然这个解决方案看起来有点乱,但是如果没有太多的编码和更少的数据库命中,它的效果会非常好。
答案 4 :(得分:1)
这里没有一个答案,因为它取决于您如何验证用户。但是,基本逻辑很简单 - 当用户登录时,根据已登录用户的列表检查其用户名或ID,如果匹配,则不对其进行身份验证(而是给他们某种消息解释)为什么他们无法登录)。
显然,您执行此操作的确切方式取决于您对用户进行身份验证以及存储用户详细信息的方式 - 如果您需要更多帮助,则需要提供更多详细信息。
答案 5 :(得分:1)
我查看了成员资格表并没有看到像“IsLoggedIn”这样的列,因此会员资格API不符合此要求。
可能是您可以使用Asp.net Cache系统并将用户标记为“LoggedIn”。通过这种方式,您可以检查额外的登录信息。
答案 6 :(得分:0)
Zhaph - Ben Duguid,Little note配置文件无法在AuthenticateRequest中访问,因为它不会在AcquireSessionState应用程序事件之前创建,所以如果他们使用这种方法(而不是页面方法)他们必须处理AcquireRequestState或PostAcquireRequestState < / p>
答案 7 :(得分:0)
当成员进入时。设置一个Random int ex。 randNo,保存缓存[UserName] = randNo,session [UserName] = randNo。 当成员访问我们检查的任何页面时:cache [UserName] == Session [UserName]没问题,否则该用户将登出。 (意思是:先登录,先退出)