javaweb用户注销后点击浏览器返回刷新页面重复登录问题的解决方法

 更新时间:2021年07月04日 15:06:43   作者:pokid  
这篇文章主要为大家详细介绍了javaweb用户注销后点击浏览器返回刷新页面重复登录问题的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近在写一个购书网站,测试注销功能时点击浏览器返回刷新浏览器,会发现原本已经注销的用户又重新登录了

想了很久在网上也找了很多办法,不过网上给出的办法大多是用js实现注销后禁止用户点击游览器返回

这个办法虽然可行,但并不是在后台真正的解决这个问题,有一种防君子不防小人的感觉 

下面把自己实现的方法记录下来

原理:

注销后点击浏览器返回刷新浏览器其实就是浏览器将原来form表单的信息重新发送了一遍

注销也就是干掉原来的session

// 注销
 private void logout(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  HttpSession session = request.getSession();
  request.setAttribute("sessionId", session.getId());
  session.removeAttribute("user");
  session.invalidate();
  response.sendRedirect(request.getContextPath() + "/index.jsp");
 } 

当注销后重定向到一个jsp页面是生成session与原来的session是不同的(jsp页面session默认是开启的) 

也就是说注销后点击浏览器返回刷新的session是新的session,从这个角度出发思考解决办法

我在原来的session里放一段数据,第一次登陆能获取到这段数据,注销后原来的session没了,点击浏览器返回刷新,新的session里没有放数据,获取的值就是null

将原来的session里的数据与新的session值进行匹配,一个有值,一个为null,肯定会匹配失败,这时可以给用户友好的提示,让用户重新登录即可。

那么原来session里的数据如何在注销后(注销了原来的session就没了)保存呢?考虑在表单里增加一个隐藏域,将原来的session里的数据放在该隐藏域中,这样注销后点击浏览器返回刷新,浏览器会自动把原来session里的数据提交一遍,无需自己手动保存(事实上手动保存可能得放在servletContext应用上下文中,没试过)

有点类似于解决表单重复提交的一种办法,但是这里不能把原来的session里数据干掉,因为注销前后不是同一个session

具体如下:在login.jsp里

<%
String token=new Random().nextLong()+"";
session.setAttribute("token", token);
%>
<form action="${pageContext.request.contextPath}/servlet/ClientServlet?operation=login" method="post">
<table style="width: 50%;">
<tr>
<td align="right">姓名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td align="right">密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<tr>
<td></td>
<td><input type="submit" value="登录"></td>
</tr>
</table>
<input type="hidden" name="token" value="${sessionScope.token}">
</form> 

在servlet中,给出友好提示并重定向到登录页面

  HttpSession session = request.getSession();
  //解决注销后后退刷新浏览器重复登录的问题
  //给一个隐藏输入域,后台获取隐藏域的值
  //注销后后退刷新浏览器会生成新的session,这样sessionToken获取为null
  //这样hiddenToken.equals(sessionToken)就一定是false
  String sessionToken = (String) session.getAttribute("token");
  String hiddenToken = request.getParameter("token");
  if (!hiddenToken.equals(sessionToken)) {
   request.setAttribute("message", "您已注销,请重新登录,2秒后转向登录页面<meta http-equiv='Refresh' content=2;url="
       + request.getContextPath() + "/client/login.jsp>");
   request.getRequestDispatcher("/client/message.jsp").forward(
     request, response);
   return;
  } 

测试:

登录

 

注销后点击浏览器返回刷新,浏览器会提示是否重新发送数据

 

点击重新发送

 

这样就解决了注销后点击浏览器返回刷新用户重新登录的问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • springboot web项目打jar或者war包并运行的实现

    springboot web项目打jar或者war包并运行的实现

    这篇文章主要介绍了springboot web项目打jar或者war包并运行的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • Java foreach循环是否可以修改数据的值问题解决方法

    Java foreach循环是否可以修改数据的值问题解决方法

    最近在做项目的时候,需要修改一个数组里面各个元素的值,foreach循环迭代数组元素时,不能改变数组元素的值,这篇文章给大家介绍Java foreach循环是否可以修改数据的值的问题及解决方法,感兴趣的朋友一起看看吧
    2024-02-02
  • Spring Cloud Hystrix 服务降级限流策略详解

    Spring Cloud Hystrix 服务降级限流策略详解

    这篇文章主要为大家介绍了Spring Cloud Hystrix 服务降级限流策略详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • SpringBoot使用AOP实现防重复提交功能

    SpringBoot使用AOP实现防重复提交功能

    这篇文章主要为大家详细介绍了SpringBoot如何使用AOP实现防重复提交功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • mybatis如何实现in传入数组查询

    mybatis如何实现in传入数组查询

    这篇文章主要介绍了mybatis如何实现in传入数组查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • MyBatisPlus3.x中使用代码生成器(全注释)

    MyBatisPlus3.x中使用代码生成器(全注释)

    这篇文章主要介绍了MyBatisPlus3.x中使用代码生成器(全注释),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Java中HashMap和TreeMap的区别深入理解

    Java中HashMap和TreeMap的区别深入理解

    首先介绍一下什么是Map。在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value
    2012-12-12
  • Mybatis映射文件之常用标签及特殊字符的处理方法

    Mybatis映射文件之常用标签及特殊字符的处理方法

    这篇文章主要介绍了Mybatis映射文件常用标签及特殊字符的处理,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • SpringMVC前后端参数映射

    SpringMVC前后端参数映射

    在web开发中我们都要进行前端传参后端取参的过程,本文主要介绍了SpringMVC前后端参数映射,针对GET, POST, PUT, DELETE 请求的参数该如何映射,感兴趣的可以了解一下
    2023-08-08
  • SpringBoot结合mockito测试实战

    SpringBoot结合mockito测试实战

    与集成测试将系统作为一个整体测试不同,单元测试更应该专注于某个类。所以当被测试类与外部类有依赖的时候,尤其是与数据库相关的这种费时且有状态的类,很难做单元测试。但好在可以通过“Mockito”这种仿真框架来模拟这些比较费时的类,从而专注于测试某个类内部的逻辑
    2022-11-11

最新评论