閱讀本文約“2.5分鐘”
本文開發環境是SpringBoot2.X版本。
對于系統而言(這里多指管理系統或部分具備登錄登出功能的系統),登錄登出是一個類權限驗證的過程,現在一般是以token進行校驗,即用戶輸入登錄信息,系統對其進行判斷,如果信息準確放行并下發一個token值到用戶的cookie中,接下來用戶的每一個操作(對系統的讀寫操作等),后臺系統都會驗證token的準確性還有存在性,以此確定用戶的登錄信息正常,登出時就清除token,如下圖所示。
那么可能意味著,我們對每一個Controller層的方法都需要加一個token驗證的代碼段,這是非常浪費時間的流程。
那么SpringBoot中就有非常方便我們處理這個同意驗證的方式,我們可以通過切面Aspect,通過定義切面類,并使用Poincut指定切入點,比如某字段開頭的全部Controller類的方法,并在Before之前進行驗證,我們就進行寫一個驗證說實現,即查詢Cookie中是否存在token字段,token字段與下發的原始token是否相同,進行驗證,如果不對,就拋出自定義的驗證異常如AuthorizeException類(其繼承RuntimeException),然后在定義了一個捕獲異常的handler,對驗證異常的返回做統一的數據返回格式。
如下流程圖所示。
還有一點,我們下發的token是要存放在哪里呢?這里的token是隨機的,暫時性的(即存在時間限制,用戶不可能永遠有權限訪問,存在過期時間),對于單應用系統可以存放在系統內存中,如設定一個全局的set等,但是現在大部分架構要考慮分布式,我推薦存放在redis中,并設定時間,這樣Aspect中的方法就僅僅多了去redis中查詢的操作,登錄時也僅需將生成的token存放到redis中。
這種方式很適合分布式應用,我在個人的開源項目中就是使用了這種方式,如果有興趣,大家可以去看看源碼MintSells
https://github.com/UncleCatMySelf/MintSells
項目的開發文檔也比較詳細。