目录
- 介绍
- 原有的用户退出功能
- 思路
- 修改include. jsp
- 添加处理用户退出请求的动作
- 总结
介绍
前面的文章我们实现了租房网平台的 、 、 等功能,本篇文章继续实现用户的登出/退出功能。
原有的用户退出功能
实际上,我们之前的版本中,只要用户登录之后,在每个页面当中已经有退出按钮,如下图:
其对应的代码在我们的 include.jsp 中:
<%@ page language="java" contentType="text/ html ; charset =UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.List" %>
<%@ page import="houserenter.entity.House" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>租房网</title>
</head>
<body>
<h1>你好,${ session Scope.userName}!欢迎来到租房网! <a href="login.html">退出</a></h1>
<br><br>
可以看到,这个退出按钮就是一个普通的链接,直接返回到登录页面而已。那这样有什么不好的地方呢?我们做这样一个实验:
- 先登录到租房网平台;
- 登录后可以打开其他页面,我这里假设打开某个房源详情页面,其URL是:
- 然后点击退出,会跳转到登录页面;
- 此时我直接在浏览器的地址栏中重新输入上述URL,可以新开一个浏览器标签页,甚至另外打开一个浏览器进程(不过必须是同一款浏览器,我这里是谷歌浏览器),敲回车;
- 结果是我跳过了登录步骤,直接打开了该房源详情页面。
结论就是这样简单的登录功能很不安全。
究其原因,其实是我们采用了session进行会话跟踪,只要session不过期, Servlet 容器(我们这里是Tomcat)中的该 session对象 就还有效,绑定到该session对象中的数据也就还有效。
不过,因为HTTP是基于TCP的,所以不同的TCP连接肯定会产生不同的session,大家有兴趣的话可以自行测试一下TCP连接和session之间的关系。
思路
所以,我们的用户退出功能必须是这样的:
- 用户点击退出按钮;
- Servlet容器必须感知到用户的退出;
- Servlet容器销毁该用户的session。
修改include.jsp
Servlet容器感知用户的退出很简单,只要发送一个请求给Servlet容器即可。
所以我们设计一个用户退出的动作,让上面的退出按钮指向该动作:
<h1>你好,${sessionScope.userName}!欢迎来到租房网! <a href="logout.action">退出</a></h1>
添加处理用户退出请求的动作
我们可以在HouseRenterController中添加处理用户退出请求的动作:
@GetMapping("/logout.action")
public ModelAndView getLogout(HttpSession session) {
System.out.println("session: " + session);
System.out.println("session id: " + session.getId());
session.invalidate();
ModelAndView mv = new ModelAndView();
mv.setViewName("redirect:login.html");
return mv;
}
重点关注的是,我们调用了HttpSession的invalidate()方法,这样我们就销毁了该session。
我们是如何得知该方法的呢?我们可以充分利用IDE的自动补足功能,然后查看每一个方法的javadoc:
可以发现invalidate()方法就是用来使此session无效,并解除绑定到它的任何对象。
总结
大家可以自行验证一下,经过这样改造后,上述问题得到解决。
- 调用HttpSession的invalidate()方法可以使会话无效。