Loading... 我们经常在登陆网站时看到一个选项,就是 **记住我**、 **n天内自动登陆**。本章我们使用 Shiro 来实现这个功能。 <!--more--> 首先需要在 `spring-shiro.xml` 中配置: ```xml <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cookie" ref="cookie"/> </bean> <bean id="cookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <!-- cookie 名称 --> <property name="name" value="rememberMe"/> <!-- cookie 过期时间 --> <property name="maxAge" value="86400"/> </bean> ``` 并将 `rememberMeManager` 添加到 `securityManager`中: ```xml <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm"/> <property name="rememberMeManager" ref="rememberMeManager"/> </bean> ``` 在之前的章节中我们提到了过滤器链中的 `user` 过滤器,以及注解中的 `@RequiresUser` 都是用来表示已登陆或 `rememberMe` 状态可访问。 我们新建一个页面 `remember.jsp`,并为其配置 `user` 过滤器: remember.jsp ```html <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>记住我</title> </head> <body> RememberMe Page </body> </html> ``` 过滤器 ```xml /remember.jsp = user ``` 当然,还要通过表单的单选框来告诉 Shiro,当前用户是否使用 `rememberMe` 功能,修改后的`login.jsp`: ```html <html> <body> <form action="login" method="post"> username : <input type="text" name="username"> <br> password : <input type="password" name="password"> <br> rememberMe: <input type="checkbox" name="rememberMe"> <br> <input type="submit" value="Login"> </form> </body> </html> ``` 并在 Controller 层接受后,将复选框选中结果配置给 Shiro: ```java @RequestMapping("login") @ResponseBody public String login(User user) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword(), user.getRememberMe()); try { subject.login(token); } catch (AuthenticationException e) { return e.getMessage(); } return "login success"; } ``` 一切配置完成后启动项目,登陆时勾选 `rememberMe`,然后关闭浏览器,重新打开,再访问 `remember.jsp` 看是否可以访问,并对比其他配置 authc 或需要授权的页面,是否可以访问。 其实他的原理就是通过 cookie 实现,勾选 `remberMe` 后登陆成功会给浏览器设置一个 cookie,以及其到期时间,请求页面时验证该 cookie 的内容是否是服务器颁发的,如果是则通过,不是则跳回登陆页面。 也可能你配置了 `rememberMe` 功能但未生效,也没有报错,那么可能是以下两种原因。 * 检查浏览器是否禁用了 Cookie * 检查是否使用了注解 `@RequiresUser`并同时在过滤器链中配置了 `/** = authc`,原因是过滤器链的优先级高于 `@RequiresUser`,在 `/** = authc` 时,表示所有请求都要认证,所以还没有到注解的验证就已经被拦截并跳回到登陆页面了。 不过 `rememberMe` 功能要慎用,且过期时间不要设置太久,因为这样即使修改密码后,原先的 cookie 在过期之前还是可以使用的。还有一个问题是,`rememberMe` 状态下无法获取用户的 Session 信息,从而也会引发其他的问题。 本章代码地址 : https://github.com/zhaojun1998/Premission-Study/tree/master/Permission-Shiro-11/ 最后修改:2022 年 05 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请我喝杯咖啡吧。