0

我正在使用数据库来存储用户详细信息,包括用户名和密码。它还有一个Security_check默认为“logged_out”的列。

每当用户登录时,我都会Security_check从验证用户(servlet)的页面将值修改为“logged_in”。每当用户点击注销按钮时,我都会明确更改Security_check为其默认值。

但是当用户在没有注销的情况下关闭浏览器时,就会出现一个大问题,因为该Security_check用户的列值仍然是“logged_in”,之后当该用户厌倦登录时,他们会收到一条错误消息,指出您正在已经登录(因为我Security_check在允许任何用户登录之前检查了,在这种情况下他们已经登录)。所以他无法登录,也无法注销,因为当他关闭浏览器时会话已过期。所以我该怎么做?

下面是 HttpSessionListener 类的代码,它不起作用:

package com.svc.session;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.sql.*;
import javax.servlet.http.HttpSession;


public class Session_Invalidator implements HttpSessionListener
{
    public Session_Invalidator()
    {
        try    
        {
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        }
        catch(Exception e) 
        {
        }
    }

    public void sessionCreated(HttpSessionEvent se)
    {
    }

    public void sessionDestroyed(HttpSessionEvent se)    
    {
        HttpSession session = se.getSession();
        String uName = session.getAttribute("userName").toString().trim();

        Connection con = null;
        PreparedStatement stmt = null;

        try 
        {
            // i am using a space between the colon and odbc because if 
            // I don't it will be converted to smile, so ignore the space
            con = DriverManager.getConnection("jdbc: odbc:CMS","","");
            stmt = con.prepareStatement("update Users set security_check=default where     login_name=?");
            stmt.setString(1, uName);
            int no = stmt.executeUpdate();
        } catch(Exception e) 
        {
        }
    }
}
4

2 回答 2

1

它认为你有两种选择。

  1. 选择一个非常短的会话超时时间(比如一两分钟)并使用 AJAX 调用实现从网页到服务器的 ping 之类的操作。因此,当用户浏览器打开并显示您的网页时,您的服务器将始终收到 ping 通知并保持会话打开。如果用户关闭浏览器,您的服务器会话将很快超时。但仍有短暂的延迟。这种方法的缺点是你会产生更多的流量,你必须找到一个合适的会话超时值。如果存在一些网络延迟,太短的值可能会导致会话超时。过长的值会增加用户无法重新登录的时间段。

  2. 这是我最喜欢的解决方案:不要被限制到根本不允许重新登录。不要将登录状态存储在数据库中。如果用户想在关闭浏览器后重新登录,则会创建一个新的服务器端会话,并且用户提供登录凭据,这很好。旧会话将在超时后被销毁。如果您使用基于容器的安全性,这是默认行为。我建议使用基于容器的安全性 (JAAS)。为什么要禁止重新登录?

以下是有关 JAAS 的一些链接:

于 2013-02-14T12:50:10.373 回答
1

我有一个解决方法来解决这个问题,它是使用一个全局对象将 sessionId 和用户 ID 一起存储,当会话超时时,我们可以从会话销毁事件中获取 sessionId,然后我们可以通过 sessionId 获取用户 ID。请查看我的博客:会话超时时更新数据库的用户状态

于 2016-11-22T10:39:57.933 回答