SpringBootSecurity學習(10)網頁版登入之記住我功能
場景
很多登入都有記住我這個功能,在使用者登陸一次以後,系統會記住使用者一段時間,在這段時間,使用者不用反覆登陸就可以使用我們的系統。記住使用者功能的基本原理如下圖:
使用者登入的時候,請求傳送給過濾器UsernamePasswordAuthenticationFilter,當該過濾器認證成功後,會呼叫RememberMeService,會生成一個token,將token寫入到瀏覽器cookie,同時RememberMeService裡邊還有個TokenRepository,將token和使用者資訊寫入到資料庫中。這樣當用戶再次訪問系統,訪問某一個介面時,會經過一個RememberMeAuthenticationFilter的過濾器,他會讀取cookie中的token,交給RememberService,RememberService會用TokenRepository根據token從資料庫中查是否有記錄,如果有記錄會把使用者名稱取出來,再呼叫UserDetailService根據使用者名稱獲取使用者資訊,然後放在SecurityContext裡。
實現類
首先來實現操作token的類,實現增刪改查功能,我們來使用redis儲存,新建類RememberMeHandler,這個類需要實現介面 PersistentTokenRepository,首先來全域性看一下類結構:
為了方便查詢,我們在記住一個使用者的時候,向redis中儲存三條資料,其中兩個是根據series查使用者名稱和根據使用者名稱查series。token定義的儲存時長為15天,這兩個定為30天。最下面的三個方法就是儲存這兩個key的方法和生成所有key的方法。四個重寫的方法就是增刪改查方法。首先來看新增:
需要記住使用者的時候,把使用者的資訊組合在一起,新增到redis中,並定義15天的過期時間。然後看修改和刪除:
都是對儲存內容的正常操作,最後看查詢:
記住使用者之後,使用者登入,查詢出使用者資訊,實現自動認證。
網上有很多使用jdbc實現的方式,也是一種不錯的選擇。
配置記住我
在security配置類中,需要配置記住我的引數名字和處理類:
注意這裡的授權配置要使用 authenticated() 。登入頁面中增加記住我:
注意這裡的引數名字 remember-me 是security記住我的預設名字。
測試
不勾選記住我,點選登入,redis中並沒有記錄token資訊,勾選記住我,點選登入,可以看到記住我的資訊記錄在redis中:
我們啟動專案,登入成功並勾選記住使用者,然後重新啟動專案,在同一個瀏覽器中訪問頁面,可以看到不用登入直接可以成功!
程式碼地址:https://gitee.com/blueses/spring-boot-security