Spring security實現記住我下次自動登錄功能過程詳解
一、原理分析
第一次登陸時,如果用戶勾選了readme選項,登陸成功后springsecurity會生成一個cookie返回給瀏覽器端,瀏覽器下次訪問時如果攜帶了這個cookie,springsecurity就會放行這次訪問。
二、實現方式
2.1 簡單實現方式
(1) 在springsecurity的配置文件中,http節點下增加一個remember-me配置
<security:http auto-config='true' use-expressions='false'> <!-- 配置鏈接地址,表示任意路徑都需要ROLE_USER權限,這里可以配置 一個逗號隔開的角色列表--> <security:intercept-url pattern='/**' access='ROLE_USER'/> <!--自定義登錄頁面--> <security:form-login login-page='/login.html' login-processing-url='/login' username-parameter='username' password-parameter='password' authentication-failure-forward-url='/failed.html' default-target-url='/index.html' /> <!--關閉csrf,默認是開啟的--> <security:csrf disabled='true'/> <security:remember-me remember-me-parameter='remembermeParamater' /> <!-- 退出 --> <security:logout invalidate-session='true' logout-url='/logout.do' logout-success-url='/login.html'/> </security:http>
其中remember-me-parameter='remembermeParamater'指定前臺傳遞的是否rememberme的參數名,前臺要傳遞的參數值是true或false
(2)前臺登錄頁面上增加一個checkbox
<form action='/login' method='post'> 用戶名:<input type='text' name='username' placeholder='請輸入用戶名'><br> 密 碼:<input type='password' name='password' placeholder='請輸入密碼'><br> 記住我:<input type='checkbox' name='remembermeParamater' value='true'> <input type='submit' value='登錄'> </form>
checkbox的name屬性要和上邊配置文件中的remember-me-parameter='remembermeParamater'保持一致。
(3)測試
啟動工程,進行登錄,登錄成功后觀察cookie,會發現服務器端返回了一個名為remember-me的cookie
現在關閉瀏覽器,再次打開并訪問,只要不清除cookie就可以直接訪問資源,不需要重新登錄。
這種方式有個弊端,瀏覽器端要攜帶的這個cookie值服務端是存放在內存中的,并沒有進行持久化,所以如果服務重啟后服務器端存儲的這個值就會丟失,瀏覽器端的rememberme就會失效。為了解決這個問題就需要將服務器端生成的這個cookie值持久化到數據庫中。
2.2 數據庫實現方式
(1)創建一張表用來持久化rememberme的記錄
-- 創建記錄rememberme記錄的表CREATE TABLE persistent_logins( username VARCHAR(64), series VARCHAR(64), token VARCHAR(64), last_used DATE );
(2)將spring-security 配置文件中的rememberme標簽的內容改為如下內容
<security:remember-me remember-me-parameter='remembermeParamater' data-source-ref='dataSource' token-validity-seconds='86400'/>
data-source-ref='dataSource'用來指定數據源,spring-security通過數據源來操作數據庫中的persistent_logins表
token-validity-seconds表示rememberme的有效時間,以秒為單位,這里的86400=24*3600表示一天
(3)測試
啟動工程,進行登錄,登錄成功后會在persistent_logins表中生成一條記錄,
關閉瀏覽器再次訪問時會根據瀏覽器中攜帶的cookie值來查找數據庫中的這條記錄,如果查詢到了就認證通過
三、區分是密碼登錄還是rememberme登錄
在用戶進行一些敏感操作時,需要區分是否是rememberme登錄,如果是需要讓用戶跳轉到登錄頁面。
在congtroller層提供一個方法來進行判斷
@GetMapping('/isRemembermeUser')public boolean isRemembermeUser(){ Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if(authentication==null){ return false; } //判斷當前用戶是否是通過rememberme登錄,是返回true,否返回false return RememberMeAuthenticationToken.class.isAssignableFrom(authentication.getClass());}
先使用密碼登錄,訪問http://localhost/user/isRemembermeUser.do,后臺接口返回false,再關閉瀏覽器再次訪問這個地址,后臺接口返回true,表示這次是使用rememberme進行的認證。
測試工程代碼的地址:工程示例
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。
相關文章:
