springboot整合shiro实现记住我功能
前言
上一篇 文章我们完成了在 thymeleaf
模板引擎中使用 shiro
标签,也就是根据不同的用户身份信息,前端页面来显示不同的页面内容。本篇文章我们来完成在登录页面的记住我的功能
springboot 整合 shiro 之实现记住我
项目依然使用 springboot整合shiro 这个项目,稍稍改动即可完成记住我的功能
配置类 ShiroConfig
完整的代码如下
@Configurationpublic class ShiroConfig {/*** 安全管理器** @param userRealm userRealm* @return defaultWebSecurityManager*/@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) {DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); defaultWebSecurityManager.setRealm(userRealm); // 实现记住我,所需要的配置defaultWebSecurityManager.setRememberMeManager(cookieRememberMeManager()); return defaultWebSecurityManager; }/*** thymeleaf模板引擎中使用shiro标签时,要用到** @return*/@Beanpublic ShiroDialect getShiroDialect() {return new ShiroDialect(); }@Beanpublic ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); // 设置登录页面urlshiroFilterFactoryBean.setLoginUrl("/user/login"); shiroFilterFactoryBean.setSuccessUrl("/user/index"); shiroFilterFactoryBean.setUnauthorizedUrl("/user/unauthorized"); // 注意此处使用的是LinkedHashMap是有顺序的,shiro会按从上到下的顺序匹配验证,匹配了就不再继续验证Map filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/layer/**", "anon"); // 静态资源放行filterChainDefinitionMap.put("/img/**", "anon"); filterChainDefinitionMap.put("/jquery/**", "anon"); // add.html页面放行filterChainDefinitionMap.put("/user/add", "authc"); // update.html必须认证filterChainDefinitionMap.put("/user/update", "authc"); // index.html必须认证filterChainDefinitionMap.put("/user/index", "user"); // 设置授权,只有user:add权限的才能请求/user/add这个urlfilterChainDefinitionMap.put("/user/add", "perms[user:add]"); filterChainDefinitionMap.put("/user/update", "perms[user:update]"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } // 实现记住我,所需要的配置@Beanpublic SimpleCookie simpleCookie() {// 这个参数是cookie的名称,对应前端的checkbox的name = rememberMeSimpleCookie simpleCookie = new SimpleCookie("rememberMe"); simpleCookie.setHttpOnly(true); // 记住我cookie生效时间1小时,单位秒simpleCookie.setMaxAge(60 * 60); return simpleCookie; } // 实现记住我,所需要的配置@Beanpublic CookieRememberMeManager cookieRememberMeManager() {CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(simpleCookie()); // rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag==")); return cookieRememberMeManager; }}
login.html
登录页面此时要拿到复选框
checkbox
是否被用户选中的状态值,选中为 true
,未选中为 false
,将这个状态值发生至后端登录接口登录 - 锐客网
controller
@Controller@RequestMapping(path = "/user")@Slf4jpublic class UserController {@GetMapping(path = "/login")public String login() {return "login"; }@GetMapping(path = "/index")public String index() {return "index"; }@GetMapping(path = "/add")public String add() {return "add"; }@GetMapping(path = "/update")public String update() {return "update"; }@GetMapping(path = "/unauthorized")public String unauthorized() {return "unauthorized"; }/*** 用户登录** @param userVO* @param bindingResult* @return*/@PostMapping(path = "/doLogin")@ResponseBodypublic ResultMap doLogin(@NotNull @Valid UserVO userVO, @NotNull BindingResult bindingResult) {// ------参数校验------if (bindingResult.hasErrors()) {String message = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage(); log.info("校验的message信息为:" + message); return new ResultMap().fail().message(message); }// 将用户名,密码交给shiroUsernamePasswordToken token = new UsernamePasswordToken(userVO.getUsername(), userVO.getPassword(), userVO.getRememberMe()); String msg; try {// shiro帮我们匹配密码什么的,我们只需要把东西传给它,它会根据我们在UserRealm里认证方法设置的来验证Subject subject = SecurityUtils.getSubject(); subject.login(token); return new ResultMap().success().action("/user/index"); } catch (AuthenticationException e) {if (e instanceof IncorrectCredentialsException) {msg = "密码错误"; } else if (e instanceof LockedAccountException) {msg = "用户被禁用"; } else if (e instanceof UnknownAccountException) {msg = "用户不存在"; } else {msg = "用户认证失败"; }}return new ResultMap().error().message(msg); }/*** 用户退出登录* 添加记住我功能了,退出登录时,除了要当前的subject退出之外,还要删除用户浏览器上的Cookie信息** @return*/@GetMapping(path = "/logout")public String logout(HttpServletResponse response) {Subject subject = SecurityUtils.getSubject(); if (subject.isAuthenticated()) {subject.logout(); Cookie cookie = new Cookie("rememberMe", null); cookie.setMaxAge(0); response.addCookie(cookie); }return "login"; }}
UserVO
类public class UserVO implements Serializable {@NotBlank(message = "账号不能为空")private String username; @NotEmpty(message = "密码不能为空")private String password; private Boolean rememberMe; // 省略set/get方法}
测试
我们以账号
jack
为例进行登录,如下文章图片
进入首页页面如下,再次查看
Cookies
数据文章图片
我们这时关闭这个首页页面,在浏览器地址栏输入
http://127.0.0.1:8080/user/index
再次进入首页页面,会发现如上图一样,可以顺利访问,说明我们的记住我功能已经实现。这时,可以再次在浏览器地址栏输入 http://127.0.0.1:8080/user/add
,进入 add.html
页面,如下文章图片
【springboot整合shiro实现记住我功能】在
Cookies
的有效期内,当你关闭浏览器之后,再次进入 add.html
页面时,无需登录直接就可以访问了,说明记住我功能已经实现了。在浏览器地址栏输入 http://127.0.0.1:8080/user/update
,进入 update.html
页面,如下文章图片
说明账号
jack
没有权限访问 update.html
页面,可以看控制台 sql
日志文章图片
源码:springboot-shiro
到此这篇关于springboot整合shiro之实现记住我的文章就介绍到这了,更多相关springboot整合shiro之实现记住我内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- Spring|Spring Boot 整合 Activiti6.0.0
- springboot使用redis缓存
- springboot整合数据库连接池-->druid
- SpringBoot中YAML语法及几个注意点说明
- springboot结合redis实现搜索栏热搜功能及文字过滤
- springboot中.yml文件的值无法读取的问题及解决
- SpringBoot整合MongoDB完整实例代码