java - 防止使用相同的用户名和密码进行多次登录

标签 java servlets

我正在开发一个应用程序,需要防止使用相同的用户名和密码进行多次登录。

如果它发生在同一台机器上,那么显然我们需要对用户 session 做一些事情,但如果他们使用相同的用户名和密码在不同的机器上登录,它也应该防止。

我们必须牢记以下几点:

  1. 如果用户在未注销的情况下关闭浏览器。
  2. 如果 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/

相关文章:

java - 调用 Servlet 时出现 500 - 内部服务器错误

java - 在一次 add() 调用中,我可以在 Solr 服务器中索引多少个文档?

java - 带有 Java 的 Eclipse 不会显示匹配的变量

java - 将列表从 JSP 发送回 servlet

java - 使用javascript更改java变量的值?

java - 当图像源是servlet时如何显示默认图像?

shell - ProcessBuilder.start() 返回 0 但不执行 shell 脚本

java - 无法在文件的第一行解析Int

java - nginx - Spring Boot 应用程序的多个反向代理(启用 Spring Security)

java - 如何在java中使用AWS Textract检索pdf中存在的表