自定义用户退出
自定义用户退出主要考虑退出后的会话如何管理以及跳转到哪个页面。HttpSecurity类的logout()方法用来处理用户退出,它默认处理路径为“/logout”的Post类型请求,同时也会清除Session和“Remember Me(记住我)”等任何默认用户配置。下面,围绕logout()这个方法来探索并讲解自定义用户退出的具体实现。
logout()用户退出方法涉及到用户退出的主要方法及说明如表1所示。
表1 用户退出相关的主要方法及说明
方法 | 描述 |
---|---|
logoutUrl(String logoutUrl) | 用户退出处理控制URL,默认为post请求的/logout |
logoutSuccessUrl(String logoutSuccessUrl) | 用户退出成功后的重定向地址 |
logoutSuccessHandler(LogoutSuccessHandler logoutSuccessHandler) | 用户退出成功后的处理器设置 |
deleteCookies(String... cookieNamesToClear) | 用户退出后删除指定Cookie |
invalidateHttpSession(boolean invalidateHttpSession) | 用户退出后是否立即清除Session(默认为true) |
clearAuthentication(boolean clearAuthentication) | 用户退出后是否立即清除Authentication用户认证信息(默认为true) |
在了解了Spring Security中关于用户退出的相关方法后,下面,继续在前面案例的基础上实现定义用户退出功能。
1.添加自定义用户退出链接
要实现自定义用户退出功能,必须先在某个页面定义用户退出链接或者按钮。为了简化操作,在之前创建的项目首页index.html上方新增一个用户退出链接,修改后的示例如文件1所示。
文件1 index.html
1 <!DOCTYPE html>
2 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <title>影视直播厅</title>
6 </head>
7 <body>
8 <h1 align="center">欢迎进入电影网站首页</h1>
9 <form th:action="@{/mylogout}" method="post">
10 <input th:type="submit" th:value="注销" />
11 </form>
12 <hr>
13 <h3>普通电影</h3>
14 <ul>
15 <li><a th:href="@{/detail/common/1}">我不是药神</a></li>
16 <li><a th:href="@{/detail/common/2}">夏洛特烦恼</a></li>
17 </ul>
18 <h3>VIP专享</h3>
19 <ul>
20 <li><a th:href="@{/detail/vip/1}">速度与激情</a></li>
21 <li><a th:href="@{/detail/vip/2}">猩球崛起</a></li>
22 </ul>
23 </body>
24 </html>
文件1中,新增了一个<form>标签进行注销控制,且定义的退出表单aciton为“/mylogout”(默认为“/logout”),方法为post。
需要说明的是,Spring Boot项目中引入Spring Security框架后会自动开启CSRF防护功能(跨站请求伪造防护,此处作为了解即可,后续小节将详细说明),用户退出时必须使用POST请求;如果关闭了CSRF防护功能,那么可以使用任意方式的HTTP请求进行用户注销。
2.自定义用户退出控制
页面中定义好用户退出链接后,不需要在Controller控制层中额外定义用户退出方法,可以直接在Security中定制logout()方法实现用户退出。打开SecurityConfig类,重写configure(HttpSecurity http)方法进行用户退出控制,示例代码如下。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
// 需要对static文件夹下静态资源进行统一放行
.antMatchers("/login/**").permitAll()
.antMatchers("/detail/common/**").hasRole("common")
.antMatchers("/detail/vip/**").hasRole("vip")
.anyRequest().authenticated();
// 自定义用户登录控制
http.formLogin()
.loginPage("/userLogin").permitAll()
.usernameParameter("name").passwordParameter("pwd")
.defaultSuccessUrl("/")
.failureUrl("/userLogin?error");
// 自定义用户退出控制
http.logout()
.logoutUrl("/mylogout")
.logoutSuccessUrl("/");
}
上述代码中,在configure(HttpSecurity http)方法中使用logout()及其相关方法实现了用户退出功能。其中,logoutUrl("/mylogout")方法指定了用户退出的请求路径,这个与index.html页面退出表单中aciton的值必须保持一致,如果退出表单使用了默认的“/logout”请求,则此方法可以省略;logoutSuccessUrl("/")方法指定了用户退出成功后重定向到“/”地址(即再次重定向到项目首页)。在用户退出后,用户会话信息则会默认清除,此情况下无需手动配置(如有需要,读者可自行定制)。
3.效果测试
重启chapter07项目进行效果测试,项目启动成功后,通过浏览器访问“http://localhost:8080/
”会直接进入到项目首页,效果如图1所示。
图1 访问项目首页效果
从图1可以看出,在项目首页上方已经出现了新添加的用户退出链接。为了演示自定义的用户退出功能效果,先访问影片详情自动跳转到自定义的用户登录页面login.html,在登录界面输入正确的用户名和密码后,效果如图2所示。
图2 访问影片详情效果
单击影片详情页中的“返回”链接回到项目首页(此时用户仍处于登录状态),单击首页中的“注销”链接进行用户注销,效果如图3所示。
图3 用户注销后效果
如图3所示,用户注销后会根据自定义设置重定向到项目首页,而此时如果再次访问影片详情则又会被拦截到用户登录页面,说明自定义的用户退出功能正确实现。