溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Spring security實現(xiàn)記住我下次自動登錄功能過程詳解

發(fā)布時間:2020-08-26 20:31:04 來源:腳本之家 閱讀:239 作者:程序曉猿 欄目:編程語言

一、原理分析

第一次登陸時,如果用戶勾選了readme選項,登陸成功后springsecurity會生成一個cookie返回給瀏覽器端,瀏覽器下次訪問時如果攜帶了這個cookie,springsecurity就會放行這次訪問。

二、實現(xiàn)方式

2.1 簡單實現(xiàn)方式

(1) 在springsecurity的配置文件中,http節(jié)點(diǎn)下增加一個remember-me配置

<security:http auto-config="true" use-expressions="false">
    <!-- 配置鏈接地址,表示任意路徑都需要ROLE_USER權(quán)限,這里可以配置
     一個逗號隔開的角色列表-->
    <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"

    />
    <!--關(guān)閉csrf,默認(rèn)是開啟的-->
    <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的參數(shù)名,前臺要傳遞的參數(shù)值是true或false

(2)前臺登錄頁面上增加一個checkbox

<form action="/login" method="post">
    用戶名:<input type="text" name="username" placeholder="請輸入用戶名"><br>
    密 碼:<input type="password" name="password" placeholder="請輸入密碼"><br>
    記住我:<input id="_spring_security_remember_me" type="checkbox" name="remembermeParamater" value="true">
    <input type="submit" value="登錄">
  </form>

checkbox的name屬性要和上邊配置文件中的remember-me-parameter="remembermeParamater"保持一致。

(3)測試

啟動工程,進(jìn)行登錄,登錄成功后觀察cookie,會發(fā)現(xiàn)服務(wù)器端返回了一個名為remember-me的cookie

Spring security實現(xiàn)記住我下次自動登錄功能過程詳解

現(xiàn)在關(guān)閉瀏覽器,再次打開并訪問,只要不清除cookie就可以直接訪問資源,不需要重新登錄。

這種方式有個弊端,瀏覽器端要攜帶的這個cookie值服務(wù)端是存放在內(nèi)存中的,并沒有進(jìn)行持久化,所以如果服務(wù)重啟后服務(wù)器端存儲的這個值就會丟失,瀏覽器端的rememberme就會失效。為了解決這個問題就需要將服務(wù)器端生成的這個cookie值持久化到數(shù)據(jù)庫中。

2.2 數(shù)據(jù)庫實現(xiàn)方式

(1)創(chuàng)建一張表用來持久化rememberme的記錄

-- 創(chuàng)建記錄rememberme記錄的表
CREATE TABLE persistent_logins
(
 username VARCHAR(64),
 series  VARCHAR(64),
 token   VARCHAR(64),
 last_used DATE 
 );

(2)將spring-security 配置文件中的rememberme標(biāo)簽的內(nèi)容改為如下內(nèi)容

<security:remember-me remember-me-parameter="remembermeParamater" data-source-ref="dataSource"
               token-validity-seconds="86400"/>

data-source-ref="dataSource"用來指定數(shù)據(jù)源,spring-security通過數(shù)據(jù)源來操作數(shù)據(jù)庫中的persistent_logins表

token-validity-seconds表示rememberme的有效時間,以秒為單位,這里的86400=24*3600表示一天

(3)測試

啟動工程,進(jìn)行登錄,登錄成功后會在persistent_logins表中生成一條記錄,

Spring security實現(xiàn)記住我下次自動登錄功能過程詳解

關(guān)閉瀏覽器再次訪問時會根據(jù)瀏覽器中攜帶的cookie值來查找數(shù)據(jù)庫中的這條記錄,如果查詢到了就認(rèn)證通過

三、區(qū)分是密碼登錄還是rememberme登錄

在用戶進(jìn)行一些敏感操作時,需要區(qū)分是否是rememberme登錄,如果是需要讓用戶跳轉(zhuǎn)到登錄頁面。

在congtroller層提供一個方法來進(jìn)行判斷

@GetMapping("/isRemembermeUser")
public boolean isRemembermeUser(){
  Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
  if(authentication==null){
    return false;
  }
  //判斷當(dāng)前用戶是否是通過rememberme登錄,是返回true,否返回false
  return RememberMeAuthenticationToken.class.isAssignableFrom(authentication.getClass());
}

先使用密碼登錄,訪問http://localhost/user/isRemembermeUser.do,后臺接口返回false,再關(guān)閉瀏覽器再次訪問這個地址,后臺接口返回true,表示這次是使用rememberme進(jìn)行的認(rèn)證。

測試工程代碼的地址:工程示例

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI