接着《Spring-Boot-shiro用户认证》,当用户成功登录后,关闭浏览器然后再打开浏览器访问http://localhost:8080/web/index,页面会跳转到登录页,之前的登录因为浏览器的关闭已经失效。

Shiro为我们提供了Remember Me的功能,用户的登录状态不会因为浏览器的关闭而失效,直到Cookie过期。

更改 ShiroConfig

继续编辑ShiroConfig,加入:

  1. /**
  2. * cookie对象
  3. * @return
  4. */
  5. public SimpleCookie rememberMeCookie() {
  6. // 设置cookie名称,对应login.html页面的<input type="checkbox" name="rememberMe"/>
  7. SimpleCookie cookie = new SimpleCookie("rememberMe");
  8. // 设置cookie的过期时间,单位为秒,这里为一天
  9. cookie.setMaxAge(86400);
  10. return cookie;
  11. }
  12. /**
  13. * cookie管理对象
  14. * @return
  15. */
  16. public CookieRememberMeManager rememberMeManager() {
  17. CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
  18. cookieRememberMeManager.setCookie(rememberMeCookie());
  19. // rememberMe cookie加密的密钥
  20. cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
  21. return cookieRememberMeManager;
  22. }

接下来将cookie管理对象设置到SecurityManager中:

  1. @Bean
  2. public SecurityManager securityManager(){
  3. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  4. securityManager.setRealm(shiroRealm());
  5. securityManager.setRememberMeManager(rememberMeManager());
  6. return securityManager;
  7. }

最后修改权限配置,将ShiroFilterFactoryBean的filterChainDefinitionMap.put("/**", "authc");更改为filterChainDefinitionMap.put("/**", "user");user指的是用户认证通过或者配置了Remember Me记住用户登录状态后可访问。

更改 login.html

在login.html中加入Remember Me checkbox:

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>登录</title>
  6. <link rel="stylesheet" th:href="@{/css/login.css}" type="text/css">
  7. <script th:src="@{/js/jquery-1.11.1.min.js}"></script>
  8. </head>
  9. <body>
  10. <div class="login-page">
  11. <div class="form">
  12. <input type="text" placeholder="用户名" name="username" required="required"/>
  13. <input type="password" placeholder="密码" name="password" required="required"/>
  14. <p><input type="checkbox" name="rememberMe" />记住我</p>
  15. <button onclick="login()">登录</button>
  16. </div>
  17. </div>
  18. </body>
  19. <script th:inline="javascript">
  20. var ctx = [[@{/}]];
  21. function login() {
  22. var username = $("input[name='username']").val();
  23. var password = $("input[name='password']").val();
  24. var rememberMe = $("input[name='rememberMe']").is(':checked');
  25. $.ajax({
  26. type: "post",
  27. url: ctx + "login",
  28. data: {"username": username,"password": password,"rememberMe": rememberMe},
  29. dataType: "json",
  30. success: function (r) {
  31. if (r.code == 0) {
  32. location.href = ctx + 'index';
  33. } else {
  34. alert(r.msg);
  35. }
  36. }
  37. });
  38. }
  39. </script>
  40. </html>

更改 LoginController

更改LoginController的login()方法:

  1. @PostMapping("/login")
  2. @ResponseBody
  3. public ResponseBo login(String username, String password, Boolean rememberMe) {
  4. password = MD5Utils.encrypt(username, password);
  5. UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
  6. Subject subject = SecurityUtils.getSubject();
  7. try {
  8. subject.login(token);
  9. return ResponseBo.ok();
  10. } catch (UnknownAccountException e) {
  11. return ResponseBo.error(e.getMessage());
  12. } catch (IncorrectCredentialsException e) {
  13. return ResponseBo.error(e.getMessage());
  14. } catch (LockedAccountException e) {
  15. return ResponseBo.error(e.getMessage());
  16. } catch (AuthenticationException e) {
  17. return ResponseBo.error("认证失败!");
  18. }
  19. }

当rememberMe参数为true的时候,Shiro就会帮我们记住用户的登录状态。启动项目即可看到效果。