如何检测用户是否从其他浏览器登录到网站?

时间:2012-07-20 18:06:28

标签: java session login

情景:

用户使用firefox登录website.com。登录凭证有效,用户将被定向到会员页面。

用户尝试使用chrome登录website.com。登录凭据有效,因为使用已经使用firefox登录,系统将抛出错误,要求用户关闭其他会话以通过chrome登录。

我该如何检测?现在,如果用户只使用一个浏览器,我可以检测到它,但是当用户使用两个不同的浏览器在不同时间登录时,它似乎会中断。

编辑*我想说这不仅仅是使用不同的浏览器,网站不应该允许多人使用相同的登录凭据登录。

4 个答案:

答案 0 :(得分:3)

我假设您的应用程序是基于j2EE / servlet的。如果是这种情况,两个浏览器彼此独立,因此它们有自己的sessionId并且可以独立运行,只要您的应用程序不会干扰。

要防止出现这种情况,实现的一种方法是在servlet中保留SessionID和UserID的哈希映射。您可以在每次成功登录时填充此信息,例如通过过滤器或阀门。在填充哈希映射时,请进行检查,以查看是否有任何其他sessionID已在使用此userID。如果使用它,请检查相应的sessionID是否仍处于活动状态。如果它不活动,请允许登录,并删除陈旧的sessionID。如果它处于活动状态,则终止其他会话并允许登录。

答案 1 :(得分:1)

在您的应用程序中,保持每次调用应用程序后更新的用户超时。您可以将用户定义为“锁定”到会话中(例如您的firefox会话),直到超时到期或用户请求注销。当您登录其他浏览(例如,chrome)时,它会检查是否存在活动会话,如果存在,则拒绝登录尝试。

我打算做一个简单的例子。这甚至不接近生产准备,仅用于说明目的。

class User {
    long lastCheckin;
    int userId;
    String username;
}

现在,当有人在应用中执行任何操作时,例如查看页面,就可以执行此操作

user.lastCheckin = System.currentTimeMillis();

现在,当某人专门请求注销时,您可以执行此操作

user.lastCheckin = 0L;

现在,当有人试图登录时,你会这样做

if(user.lastCheckin + PREDEFINED_TIMEOUT > System.currentTimeMillis()) {
    return new LoginResponse(false,"User is active in another session.");
}

答案 2 :(得分:1)

如果您使用的是Spring Security,则可以通过配置文件中的参数指定。

如果只是简单的java - 在登录期间将用户的会话ID放到某个存储中;当他再次尝试登录时,你应该禁止它。 但是,当用户在关闭浏览器后很长时间处于存储状态时,您需要避免出现这种情况(一种可能的解决方案是短会话超时+保持活动请求)

答案 3 :(得分:1)

您可以在应用程序范围变量(如ServletContext)上存储已登录用户的映射。例如,在您的auth servlet上,您可以执行以下操作:

Map<String,String> activeUsers = request.getSession().getServletContext().getAttribute("__ONLINE_AUTHENTICATED_USERS");
//if null, context hasn't been prepared yet, create and attach a new one?2

但你必须要小心。作为应用程序范围变量,您需要确保一些线程安全性,这是servletContext.setAttribute / getAttribute提供的内容(例如,那些操作不是线程安全的)。您可以通过使用某种应用程序生命周期监听器来“初始化”servletContext以使用户映射来处理此问题。这样您就不必担心set / getAttribute。你还需要考虑地图操作本身(例如,使用j.u.c.ConcurrentHashMap吗?)。

当用户退出或会话超时时,您还必须注意清理(例如从地图中删除)。

您还必须考虑用户可能会通过这种方法将自己锁定很长时间(例如,关闭浏览器但不正确注销,会话需要在映射清除之前超时)。

编辑: 您还需要考虑可伸缩性,这取决于您的应用程序。您期待一百万在线用户吗?或者只有几万个?

相关问题