【问题标题】:Invalidate session in Logout Servlet [duplicate]注销 Servlet 中的会话无效 [重复]
【发布时间】:2013-03-14 20:31:40
【问题描述】:
HttpSession session  = request.getSession();
try
{      
    session.removeAttribute("logonSessData");
    session.invalidate();                               
    String pageToForward = request.getContextPath();
    response.sendRedirect(pageToForward);           
}
catch (Exception sqle)
{
    System.out.println("error UserValidateServlet message : " + sqle.getMessage());
    System.out.println("error UserValidateServlet exception : " + sqle);
}

在注销 servlet 中,我在 doPostdoGet 方法中编写了上述代码。注销后它显示登录屏幕,然后如果我按返回按钮,它会在注销前显示上一个屏幕,然后如果我点击任何页面,它会显示“HTTP 状态 500”,现在如果我按 F5 那么它正在加热登录 Servlet 并获得用户的完全访问权限。

如何停止这个问题显示在使用后退按钮注销后 F5 用户不能使用任何页面?

【问题讨论】:

  • 也许您的应用程序的其他一些服务也在使用该会话,而您正在使整个会话无效。尝试只删除身份验证属性而不调用invalidate()
  • 如果您仍然无效,则无需调用 session.removeAttribute(...)。

标签: java jsp servlets


【解决方案1】:

这将创建一个新会话

HttpSession ss = request.getSession(true); //creates a new session.
  if(ss.isNew()){
    ss.invalidate();  //this clears the session
    ss = request.getSession(true); // creates a new session 
    }

【讨论】:

  • 不确定您是否很好地阅读了这个问题。这并不能回答实际提出的问题,也不能解决这里的问题。
【解决方案2】:

1)当您点击浏览器上的后退按钮时,由于浏览器缓存,您将获得上一页。

2)当您在支持后单击任何页面时,您将获得状态 500,因为由于会话对象已经无效而出现空指针异常。

3)当您刷新新请求将发送到您的 servlet 或 JSP 时,您正在调用 request.getSession(); 方法,该方法正在为您创建新的会话对象。

因此,您将再次获得对所有页面的完全访问权限。

为避免此问题,您可以按照以下步骤操作。

1)在应用程序中创建一个servlet 例如:LoginCheckerServlet

2) 对于上面的 servlet,给出 url 模式 /*

3)所以servlet会针对所有的请求执行

4) 现在在LoginCheckerServlet 中检查请求参数中的用户名和密码

5)如果他们来了,执行登录检查操作并显示欢迎页面

6)如果用户名密码不来,有两种含义

     i)user is already logged in 

    ii)user is trying to access your app illegally

7) 现在调用request.getSession(false); 方法,如果该用户已经存在会话,则该方法将为您提供会话对象,因此您可以在信任用户的情况下重定向到欢迎页面。

8)request.getSession(false); 如果此用户不存在会话,则会给您空值。

9)如果你在请求参数中没有得到用户名和密码,并且request.getSession(false);给你空值意味着用户试图在没有登录的情况下访问你的应用程序,现在你可以愉快地显示被禁止的页面。

【讨论】:

    【解决方案3】:

    在每个 servlet 中,检查 Session 是否为空。如果 session 不为空,则只做请求处理,否则重定向到登录页面。

    HttpSession session  = request.getSession();
    
    if(Session !=null)
    {
    try
    {      
        // acutal servlet actions
    
    }else
    {
    
      // redirect to login page
    
     }
    

    如果您在上面的代码中添加对会话的空检查也会很好。

    HttpSession session  = request.getSession();
    if(session !=null)
    try
    {      
        session.removeAttribute("logonSessData");
        session.invalidate();                               
        String pageToForward = request.getContextPath();
        response.sendRedirect(pageToForward);           }
    catch (Exception sqle)
    {
        System.out.println("error UserValidateServlet message : " + sqle.getMessage());
        System.out.println("error UserValidateServlet exception : " + sqle);
    }
    }else
    {
      //session already null/ expired
    }
    

    【讨论】:

    • 我不知道为什么我被否决了,但肯定高于 null 检查将避免可能导致 HTTP 状态 500 的 NullPointer 异常。
    • 当您注销并单击浏览器后退按钮时,它肯定会返回到缓存的上一页。当您单击任何按钮或按 f5 时,请求将失败,HTTP 状态为 500,因为会话不再可用。
    • 我否决了它,因为:1)它不能解决 OP 的具体问题,2)它不是 DRY,3)它有一个编译错误,以及 4)它不属于 servlet一点也不。请参阅重复的问题以获得正确答案。
    【解决方案4】:

    你做的很好。浏览器正在缓存以前的页面,当您单击后退按钮时,它会转到上一个缓存的页面。

    您需要添加不允许浏览器缓存页面的缓存头。

    Cache-Control: no-cache
    

    【讨论】:

    • 您已经接近了,但仅此标头是不够的。有关正确的标题集,请参阅重复的问题链接。
    • 添加如下coderesponse.setHeader("Cache-Control", "no-cache, no-store"); response.setHeader("Pragma", "no-cache");
    • 您不应将其添加到注销的响应中,就像 Ramesh 错误暗示的那样。您应该使用 servlet 过滤器将其添加到每个受限页面的响应中(可以与您检查登录用户的位置相同)。另外,这些标头仍然不完整,并且不兼容跨浏览器。另请参阅重复问题中的答案。
    • @BalusC 感谢您关注和纠正我!!!!
    • @Vishal:查看问题的编辑历史。一群 /review 猴子在被关闭后重新打开了这个问题,只是为了获得激励。由于系统损坏,我无法再次为欺骗投票。
    【解决方案5】:

    你需要做的是根据会话将会话设置为一个属性。

    request.getSession().setAttribute("sess",request.getSession());

    使用它与当前会话进行比较。如果此比较失败,则重定向到登录页面。这应该在每个页面中完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-04
      • 2021-03-09
      • 2011-04-29
      • 1970-01-01
      • 2015-08-14
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多