spring security實現記住我下次自動登陸功能

spring security實現記住我下次自動登陸功能

上一篇: spring security的BCryptPasswordEncoder加密和對密碼驗證的原理java

1、原理分析

第一次登錄時,若是用戶勾選了readme選項,登錄成功後springsecurity會生成一個cookie返回給瀏覽器端,瀏覽器下次訪問時若是攜帶了這個cookie,springsecurity就會放行此次訪問。git

2、實現方式

2.1 簡單實現方式

(1) 在springsecurity的配置文件中,http節點下增長一個remember-me配置spring

<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或falsesql

(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"保持一致。express

(3)測試瀏覽器

啓動工程,進行登陸,登陸成功後觀察cookie,會發現服務器端返回了一個名爲remember-me的cookie服務器

如今關閉瀏覽器,再次打開並訪問,只要不清除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值來查找數據庫中的這條記錄,若是查詢到了就認證經過

3、區分是密碼登陸仍是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進行的認證。

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

相關文章
相關標籤/搜索