我們經常在登陸網站時看到一個選項,就是 記住我、 n天內自動登陸。本章我們使用 Shiro 來實現這個功能。
首先需要在 spring-shiro.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
中:
<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
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>記住我</title> </head> <body> RememberMe Page </body> </html>
過濾器
/remember.jsp = user
當然,還要通過表單的單選框來告訴 Shiro,當前用戶是否使用 rememberMe
功能,修改後的login.jsp
:
<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:
@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/