最近在写一个购书网站,测试注销功能时点击浏览器返回刷新浏览器,会发现原本已经注销的用户又重新登录了
想了很久在网上也找了很多办法,不过网上给出的办法大多是用js实现注销后禁止用户点击游览器返回
这个办法虽然可行,但并不是在后台真正的解决这个问题,有一种防君子不防小人的感觉
下面把自己实现的方法记录下来
原理:
注销后点击浏览器返回刷新浏览器其实就是浏览器将原来form表单的信息重新发送了一遍
注销也就是干掉原来的session
1
2
3
4
5
6
7
8
9
|
// 注销 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里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<% 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中,给出友好提示并重定向到登录页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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 ; } |
测试:
登录
注销后点击浏览器返回刷新,浏览器会提示是否重新发送数据
点击重新发送
这样就解决了注销后点击浏览器返回刷新用户重新登录的问题。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。