Spring boot后台搭建二集成Shiro添加Remember Me
上一片文章实现了用户验证 查看
当用户成功登录后,关闭浏览器,重新打开浏览器访问http://localhost:8080,页面会跳转到登录页,因为浏览器的关闭后之前的登录已失效
Shiro提供了Remember Me的功能,用户的登录状态不会因为浏览器的关闭而失效,直到Cookie过期
1.修改ShiroConfig
(1)添加
/** * cookie对象 * @return */ public SimpleCookie rememberMeCookie() { // 设置cookie名称,对应login.html页面的<input type="checkbox" name="rememberMe"/> SimpleCookie cookie = new SimpleCookie("rememberMe"); // 设置cookie的过期时间,单位为秒,这里为一天 cookie.setMaxAge(86400); return cookie; } /** * cookie管理对象 * @return */ public CookieRememberMeManager rememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); // rememberMe cookie加密的密钥 cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag==")); return cookieRememberMeManager; }
(2)将cookie管理对象设置到SecurityManager
修改securityManager()为
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); securityManager.setRememberMeManager(rememberMeManager());//新加 return securityManager; }
(3)改权限配置
将ShiroFilterFactoryBean的
filterChainDefinitionMap.put("/**", "authc")
修改为
filterChainDefinitionMap.put("/**", "user");
说明:
user
指的是用户认证通过或者配置了Remember Me记住用户登录状态后可访问
2.修改login.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" th:href="@{/css/login.css}" type="text/css"> <link rel="stylesheet" th:href="@{css/iCheck/minimal/blue.css}" type="text/css"> <link rel="stylesheet" th:href="@{css/app.css}" type="text/css"> <script th:src="@{/js/jquery.min.js}"></script> </head> <body> <div class="login-page"> <!-- Form--> <div class="form"> <div class="form-toggle"></div> <div class="form-panel one"> <div class="form-header"> <h1>账户登录</h1> </div> <div class="form-content"> <div class="form-group"> <label>用户名</label> <input type="text" name="account" /> </div> <div class="form-group"> <label>密码</label> <input type="password" name="password" /> </div> <div class="form-group" style="margin: 0px;"> <p> <input type="checkbox" name="rememberMe" /> 记住我</p> </div> <div class="form-group"> <button onclick="login()" id="loginButton">登录</button> </div> </div> </div> </div> </div> </body> <script th:inline="javascript"> var ctx = [[@{/}]]; function login() { var account = $("input[name='account']").val(); var password = $("input[name='password']").val(); var rememberMe = $("input[name='rememberMe']").is(':checked'); $.ajax({ type: "post", url: ctx + "login", data: {"account": account,"password": password,"rememberMe": rememberMe}, dataType: "json", success: function (r) { if (r.code == 0) { location.href = ctx + 'index'; } else { alert(r.msg); } } }); } </script> </html>
3.修改LoginController
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@PostMapping("/login") @ResponseBody public ResponseBo login(String account, String password, Boolean rememberMe) { System.out.println(rememberMe); // 密码MD5加密 password = MD5Utils.encrypt(account, password); System.out.println(password); UsernamePasswordToken token = new UsernamePasswordToken(account, password); rememberMe = rememberMe == null ? false : rememberMe; //null=>false token.setRememberMe(rememberMe); //UsernamePasswordToken token = new UsernamePasswordToken(username, password,rememberMe); // 获取Subject对象 Subject subject = SecurityUtils.getSubject(); try { subject.login(token); if (rememberMe) System.out.println("rememberMe--------"); return ResponseBo.ok(); } catch (UnknownAccountException e) { return ResponseBo.error(e.getMessage()); } catch (IncorrectCredentialsException e) { return ResponseBo.error(e.getMessage()); } catch (LockedAccountException e) { return ResponseBo.error(e.getMessage()); } catch (AuthenticationException e) { return ResponseBo.error("认证失败!"); } }
rememberMe选中的时候,Shiro就会帮忙记住用户的登录状态
说明:
如果遇到下面错误
2019-06-24 15:37:49.620 WARN 12952 --- [nio-8088-exec-2] o.a.shiro.mgt.DefaultSecurityManager : Delegate RememberMeManager instance of type [org.apache.shiro.web.mgt.CookieRememberMeManager] threw an exception during onSuccessfulLogin. RememberMe services will not be performed for account [com.sfn.bms.system.model.User@86fc436].
org.apache.shiro.io.SerializationException: Unable to serialize object [com.sfn.bms.system.model.User@86fc436]. In order for the DefaultSerializer to serialize this object, the [org.apache.shiro.subject.SimplePrincipalCollection] class must implement java.io.Serializable.
相关文章
- 关于spring boot自动注入出现Consider defining a bean of type ‘xxx‘ in your configuration问题解决方案
- Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part C JPA)
- Nginx + Spring Boot 轻松实现负载均衡,还有谁不会??
- 掌握这些 Spring Boot 启动扩展点,已经超过 90% 的人了!
- Spring Boot 实现万能文件在线预览
- Spring boot集成plumelog日志系统
- Spring Boot 整合 Elastricsearch + LogStash + Kibana
- Spring Boot集成websocket
- spring boot的基本配置——spring boot的web开发——Thymeleaf模板引擎———通过HttpSession session的session.setAttribute返回数据给
- Spring Boot Version Compatibility
- spring boot微服务通用部署启动脚本
- Spring Boot的单元测试(概念)
- Spring Boot | 集成MapStruct实现不同类型Java对象间的自动转换
- Spring Boot Actuator集成demo
- Spring Boot的测试框架(二)
- Spring Boot中使用MongoDB数据库的方法
- Spring Boot 2.0官方文档之 Actuator详解编程语言
- Spring Boot 性能优化详解编程语言
- Spring Boot全局支持CORS(跨源请求)的配置方法详解编程语言
- Spring Boot日志集成实战详解编程语言
- Spring Boot 集成 Mybatis 实现双数据源详解编程语言
- Spring Boot(十三):spring boot小技巧详解编程语言
- spring boot 配置随机数那些小技详解编程语言
- spring boot 集成disconf详解编程语言
- Spring queryForObject方法:查询的结果以对象类型返回
- Spring Boot 2 快速教程:WebFlux 集成 Thymeleaf(五)