引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

今天咱們就使用這種方式對 Session 存儲方式進行改造,將其統一存儲到 Redis 中。redis

實現方案

咱們先來想一下,若是咱們不依靠任何框架,本身如何實現後端 Session 集中存儲。算法

這裏咱們假設咱們的網站除了某些頁面,好比首頁能夠直接訪問之外,其餘任何頁面都須要登陸以後才能訪問。spring

若是須要實現這個需求,這就須要咱們對每一個請求都進行鑑權,鑑權目的是爲了判斷用戶是否登陸,判斷用戶角色。數據庫

若是用戶沒有登陸,咱們須要將請求強制跳轉到登陸頁面進行登陸。json

用戶登陸以後,咱們須要將登陸獲取到的用戶信息存儲到 Session 中,這樣後面請求鑑權只須要判斷 Session 中是否存在便可。後端

知道整個流程以後,其實實現原理就不是很難了。瀏覽器

咱們可使用相似 AOP 的原理,在每一個請求進來以後,都先判斷 Session 中是否存在用戶信息,若是不存在就跳轉到登陸頁。session

整個流程以下所示:app

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

咱們能夠利用 Servelt Filter 實現上述流程,不過上述整套流程,Spring 已經幫咱們實現了,那咱們就不用重複造輪子了。框架

咱們可使用 Spring-Session 與 Spring-security 實現上述網站的流程。

Spring-Session 是 Spring 提供一套管理用戶 Session 的實現方案,使用 Spring-Session以後,默認 WEB 容器,好比 Tomcat,產生的 Session 將會被 Spring-Session 接管。

除此以外,Spring-Session 還提供幾種常見後端存儲實現方案,好比 Redis,數據庫等。

有了 Spring-Session 以後,它只是幫咱們解決了 Session 後端集中存儲。可是上述流程中咱們還須要登陸受權,而這一塊咱們可使用 Spring-security 來實現。

Spring-security 能夠維護統一的登陸受權方式,同時它能夠結合 Spring-Session 一塊兒使用。用戶登陸受權以後,獲取的用戶信息能夠自動存儲到 Spring-Session 中。

好了,不說廢話了,咱們來看下實現代碼。

下述使用 Spring Boot 實現, Spring-Boot 版本爲:2.3.2.RELEASE

Spring Session

首先咱們引入 Spring Session 依賴,這裏咱們使用 Redis 集中存儲 Session 信息,因此咱們須要下述依賴便可。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

若是不是 Spring Boot 項目,那主要須要引入以下依賴:

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

引入依賴以後,咱們首先須要在 application.properties增長 Session 相關的配置:

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

配置完成以後,Spring Session 就會開始管理 Session 信息,下面咱們來測試一下:

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

當咱們訪問上面地址以後,訪問 Redis ,能夠看到存儲的 Session 信息。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

默認狀況下,Session 默認使用HttpSession 序列化方式,這種值看起來不夠直觀。咱們能夠將其修改爲 json 序列化方式,存儲到 redis 中。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

修改以後 Redis 鍵值以下所示:

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

ps:這裏 Redis 鍵值含義,下次分析源碼的時候,再作分析。

Spring Session 還存在一個 @EnableRedisHttpSession,咱們能夠在這個註解上配置 Spring Session 相關配置。

@EnableRedisHttpSession(redisNamespace = "test:session")

須要注意的是,若是使用這個註解,將會致使 application.properties Session 相關配置失效,也就是說 Spring Session 將會直接使用註解上的配置。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

這裏比較推薦你們使用配置文件的方式。

好了,Spring Session 到這裏咱們就接入完成了。

Spring security

上面咱們集成了 Spring Session,完成 Session 統一 Redis 存儲。接下來主要須要實現請求的登錄鑑權。

這一步咱們使用 Spring security 實現統一的登錄鑑權服務,一樣的框架的還有 Shiro,這裏咱們就使用 Spring 全家桶。

首先咱們須要依賴的相應的依賴:

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

引入上面的依賴以後,應用啓動以後將會生成一個隨機密碼,而後全部的請求將會跳轉到一個 Spring security 的頁面。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

這裏咱們須要實現本身業務的登錄頁,因此咱們須要自定義登陸校驗邏輯。

在 Spring security 咱們只須要實現 UserDetailsService接口,重寫loadUserByUsername方法邏輯。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

上面代碼實現,這裏主要在內存固定用戶名與密碼,真實環境下,咱們須要修改爲從數據庫查詢用戶信息。

接着咱們須要把 UserServiceImpl 配置到 Spring security 中。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

上面的配置中,密碼部分咱們使用 BCrypt 算法加密,這裏須要注意,加密與解密須要使用同一種方式。

接着咱們須要實現一個自定義的登錄頁面,這裏就懶得本身寫了,直接使用 spring-session-data-redis 頁面。

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

這裏須要注意一點,這裏 form 表單的請求地址使用 /auth/login,咱們須要在下面配置中修改,默認狀況下登陸請求的地址須要爲 /login。

接着咱們在上面的 SecurityConfig 類增長相應配置方法:

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

這個方法可能比較長,重點解釋一下:

  • authorizeRequests方法內須要指定那些頁面須要鑑權,這裏咱們指定靜態資源無需登陸鑑權,其餘請求咱們都須要登陸鑑權
  • formLogin 方法內修改默認的登陸頁面地址,以及登陸的請求地址。
  • logout在這裏面能夠配置登出的相關配置。
  • rememberMe開啓這個功能以後,當內部 Session 過時以後,用戶還能夠根據用戶瀏覽器中的 Cookie 信息實現免登陸的功能。

最後咱們須要配置一些頁面的跳轉地址:

引入兩個依賴以後,我一週內就完成了網站的登陸改造|實戰開發

 

到此爲止,咱們已經集成 Spring-Session 與 Spring-security 完成完整的網站的登陸鑑權功能。從這個例子能夠看到,引入這個兩個框架以後,咱們只須要按照 Spring 規範開發便可,其餘複雜實現原理咱們都不須要本身實現了,這樣真的很方便

相關文章
相關標籤/搜索