我正在开发一个应用程序,需要防止使用相同的用户名和密码进行多次登录。
如果它发生在同一台机器上,那么显然我们需要对用户 session 做一些事情,但如果他们使用相同的用户名和密码在不同的机器上登录,它也应该防止。
我们必须牢记以下几点:
- 如果用户在未注销的情况下关闭浏览器。
- 如果 session 超时。
我将不胜感激。
最佳答案
If user close the browser without logout.
特别是这种情况难以检测且不可靠。你可以使用 beforeunload
Javascript 中的事件,但您完全依赖于浏览器是否启用了 JS 以及特定浏览器是否支持此非标准事件(例如 Opera 不支持)。这也是我建议只注销以前登录的用户而不是阻止登录的主要原因之一。对于用户“忘记”从另一台计算机注销的情况,这也更加用户友好和安全。
最简单的方法是让 User
有一个static Map<User, HttpSession>
变量并让它实现 HttpSessionBindingListener
(以及 Object#equals()
和 Object#hashCode()
)。
public class User implements HttpSessionBindingListener {
// All logins.
private static Map<User, HttpSession> logins = new HashMap<User, HttpSession>();
// Normal properties.
private Long id;
private String username;
// Etc.. Of course with public getters+setters.
@Override
public boolean equals(Object other) {
return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
}
@Override
public int hashCode() {
return (id != null) ? (this.getClass().hashCode() + id.hashCode()) : super.hashCode();
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
HttpSession session = logins.remove(this);
if (session != null) {
session.invalidate();
}
logins.put(this, event.getSession());
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
logins.remove(this);
}
}
当您登录 User
如下:
User user = userDAO.find(username, password);
if (user != null) {
request.getSession.setAttribute("user", user);
} else {
// Show error.
}
然后它将调用 valueBound()
这将从 logins
中删除任何以前登录的用户映射并使 session 无效。
当您注销 User
如下:
request.getSession().removeAttribute("user");
或者当 session 超时时,然后 valueUnbound()
将被调用,从 logins
中删除用户 map 。
关于java - 防止使用相同的用户名和密码进行多次登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1932091/