一個輕量級的單點登錄解決方案

會話狀態管理是每個IT系統必不可少的一個組成部分,在集羣架構或分佈式架構下的會話管理是一個比較頭疼的問題,一般採用的方案有session 同步,IP粘連和分佈式session等,session同步指的是在每個服務器之間進行session數據的同步,這種方案在少量用戶下沒啥問題,但是一旦同時在線的用戶變多,服務器的負擔就會很大,IP粘連一般用在對等集羣架構下,其實是一種僞實現,就是把某個用戶跟某臺服務器綁定了,如果這臺機器宕機,那用戶還是需要重新登錄,分佈式session是將session數據存儲到一個第三方系統中,通常是redis,這樣再多個服務器節點之間共享redis服務,從而實現session共享。

其中還有一種解決分佈式會話管理的技術,這就是jwt,jwt全稱是json web token,是一種靜態的用戶身份標識,具體概念就不在這羅列了,可以看看官方介紹https://jwt.io/introduction/。

在這裏插入圖片描述
上面這個架構是我在一個基於dubbo的分佈式系統中用到的,下面說說具體的流程。

首先,用戶進行登錄,提交用戶名和密碼,氫請求通過API網關到SSO系統,SSO登錄接口會調用用戶服務進行用戶名和密碼的校驗(模板採用隨機salt的方式進行MD5加密),驗證通過後,SSO接口爲用戶生成一個token和一個jwt,token用來標識一次有效登錄,jwt中封裝了userid,然後以(userid:token,jwd)的形式再存儲在redis中,最終返回給客戶端。

客戶端將token設置到cookie中(token=tokenValue),把jwt設置到請求頭中(Auth=jwtValue),當請求需要登錄的接口時,API網關的Filter會攔截token和jwt,並調用SSO接口進行有效性驗證,如果token和jwt無效則直接返回響應,如果有效,則SSO接口解析jwt並返回其中的userid,然後API網關Filter將userid設置到request對象頭中,供後端服務使用。

以上就是一次登錄和鑑權過程。另外還有兩個點向說明一下,第一個jwt本身帶有過期時間,爲啥還要在redis中存一份,我是這麼想的,首先可以增加一層校驗,進一步避免jwt被篡改後通過驗證的可能性,其次是給後端提供了一個控制jwt有效性的入口,因爲jwt是一種靜態身份表示,一經生成不能修改,那麼在某些情況下如果想強制剔除某些用戶的話就無能爲力了。另外一點是關於jwt安全性的問題,這裏我採用了AES對jwt進行對稱加密,返回給客戶端的jwt值時加密後的值,當進行驗證時需要先進行解密,由於AES祕鑰都在服務端,所以能進一步保障jwt被篡改的可能性。

這個方案比較適合那些比較輕量級的系統,實現起來簡單、安全。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章