一、前言
不管是作爲一個後臺管理系統,還是客戶端應用系統,登錄都是一個必備的功能,基本上每個程序員都寫過登錄接口,基本就是用戶輸入賬號密碼然後去數據查比對是否一樣,一樣就返回登錄成功,不一樣就返回登錄失敗。當然這只是登錄最簡單的實現,其實登錄是一個非常有技術含量的功能,本系統沒有使用任何權限框架,而是基於JWT
+Redis
自己手擼實現的一套鑑權邏輯,採用了B、C端多賬號體系認證,B端代表後臺用戶,C端代表前臺用戶,可以根據不同的端來處理登錄邏輯,目前只實現了B端登錄,如需C端請自行擴展。
二、登錄設計
本系統中登錄分爲賬號密碼
登錄、手機號
登錄和第三方
登錄,目前已經實現前面兩種,第三種需要自己拓展實現。
2.1 賬號密碼登錄
基本流程圖:
進入登錄頁面之後會讀取系統配置判斷是否需要驗證碼
,如果需要驗證碼就會去請求驗證碼接口獲取驗證碼並顯示在頁面上。
除了用戶名密碼,還需要將驗證碼和請求號傳入登錄接口供後端驗證,不然這個驗證碼就形同虛設了。
後端接收到前端傳過來的賬號密碼和驗證碼,判斷驗證碼是否正確,解密之後的密碼是否和數據庫一致,如果吻合,則生成token返回給前端
在ExecLoginB方法中,主要會做三件事:
生成token
:前端拿到token去請求接口將token寫入redis
:只有redis存在的token纔有權限請求接口發佈登錄事件總線
:更新用戶信息,登錄Ip等信息。
2.2 手機號登錄
基本流程圖:
點擊獲取驗證碼
按鈕獲取短信驗證碼
接下的流程就和賬號密碼登錄一樣了,攜帶手機號和驗證碼取請求手機登錄接口就行。
三、單用戶登錄
單用戶登錄是指在同一時間,同一客戶端只允許一個人訪問系統,當用戶登錄之後,其他已經登錄的用戶將被強制下線。本系統默認是多用戶登錄的,也就是一個賬號可以在多個瀏覽器登錄,想要開啓單用戶登錄,只需要在系統設置裏打開單用戶登錄開關就行。
原理也是很簡單,我們登錄之後的token都會存在redis
,當用戶請求接口的時候會攜帶redis,如果redis有該token就允許請求,否則返回401,這裏我們只要將其他token給去了,只留當前用戶的token。
順便通知其他用戶下線。
其他用戶會收到下線消息。
四、自動刷新token
自動刷新token,也叫無感刷新,因爲我們使用的是token認證,但是token又是無狀態的,token到期之後攜帶請求會報401錯誤,如果用戶用的好好的突然需要重新登錄,那麼用戶體驗就不是很好,所以我們需要系統後臺刷新token,而因爲我們使用的Furion
框架,可以非常容易的實現該功能。
4.1 後端登錄部分
當用戶登錄成功之後,返回 accessToken
字符串,之後通過 JWTEncryption.GenerateRefreshToken()
獲取 刷新Token
,並通過響應報文頭返回,用戶登錄成功之後把 accessToken
和 refreshToken
一起返回給客戶端存儲起來。
4.2 後端授權 Handler
部分
JwtHandler中重寫授權處理
當自動刷新token之後,存儲在redis中的token也需要更新。
4.3 客戶端部分
客戶端每次請求需將 accessToken
和 refreshToken
放到請求報文頭中傳送到服務端,格式爲:
Authorization: Bearer 你的token
X-Authorization: Bearer 你的刷新token
具體體現在前端項目中的utils
文件夾中的request.js
,通過前端通過decryptJWT
方法解析token,判斷是否快過期了。
如果 Token
過期,那麼 Furion
將自動根據有效期內的 refreshToken
自動生成新的 AccessToken
,並在 響應報文頭 中返回,如
access-token: 新的token
x-access-token: 新的刷新token
前端需要獲取 響應報文頭
新的 token 和刷新 token 替換之前在客戶處存儲舊的 token 和刷新 token。