当用户会话使用相同的凭据登录两次时,如何使他会话失效

2022-09-02 10:13:39

我正在使用JSF 1.2和Richfaces和Facelets。

我有一个应用程序,其中包含许多会话范围的Bean和一些应用程序Bean。

用户使用 Firefox 登录。创建会话时 ID=“A”;然后,他打开Chrome并使用相同的凭据再次登录。创建 ID=“B” 的会话。

创建会话“B”时,我希望能够销毁会话“A”。如何做到这一点?

也。当Firefox中的用户做任何事情时,我希望能够显示一个弹出窗口或某种通知,说“您已注销,因为您从其他地方登录”。

我有一个会话Listener,他跟踪创建和销毁的会话。问题是,我可以将HTTPSession对象保存在应用程序范围的Bean中,并在检测到用户登录两次时将其销毁。但有些事情告诉我,这是错误的,行不通。

JSF 是否在服务器端的某个位置跟踪会话?如何通过标识符访问它们?如果没有,当用户登录两次时,如何踢出他的第一次登录?


答案 1

独立于 DB 的方法是让 有一个变量并实现 HttpSessionBindingListener (和 Object#equals()Object#hashCode())。这样,您的web应用程序在不可预见的崩溃后仍将运行,这可能会导致数据库值无法更新(您当然可以创建一个在webapp启动时重置数据库,但这只会越来越多)。Userstatic Map<User, HttpSession>ServletContextListener

下面是 应如下所示:User

public class User implements HttpSessionBindingListener {

    // All logins.
    private static Map<User, HttpSession> logins = new ConcurrentHashMap<>();

    // 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) {
    sessionMap.put("user", user);
} else {
    // Show error.
}

然后它将调用,这将从地图中删除任何先前登录的用户并使会话无效。valueBound()logins

当您注销时,如下所示:User

sessionMap.remove("user");

或者当会话超时时,将调用 ,这将从映射中删除用户。valueUnbound()logins


答案 2
  1. 在数据库中创建整数字段userLoggedInCount
  2. 每次登录都会递增该标志并将结果存储在会话中。
  3. 在每个请求中检查数据库中的值和会话中的值,如果会话中的值小于 DB 中的值,则会话中的值并递减数据库中的值invalidate()
  4. 每当会话被销毁时,该值也会递减。

推荐