JWT-無狀態方案處理

1.JWT的優勢在於無狀態,如果非要結合redis等相關nosql來進行一些方案的處理,我覺得是沒有必要的。這樣還不如直接使用session集羣。

2.那麼針對JWT就會有幾個問題

(1)退出登錄,需要把token無效化

(2)修改密碼,需要把token無效化

(3)單用戶登錄,需要進行判斷

其實(1)(2)是屬於差不多的類型。

這兩種情況的處理就比較相似了。

那麼我們首先考慮jwt存的是什麼,我們假設爲{"userId":1,"version":1}

我們先考慮簡單處理—redis

退出或者改密碼的時候我建議把version提升一個版本(2)。以userId爲key,version爲value放進hash裏,那麼每次jwt進來的時候就會去redis中根據userID獲取version,發現有的話,那麼就會對比version,如果目前version低於redis中的version的話,那麼就會攔截下來。

好了 ,這就是一個簡單的處理方式。那麼接下來分析一下優缺點。

優點:

(1)不用考慮數據的一致性,因爲都是從一個地方進行讀取

缺點:

(1)每個jwt都需要去redis中進行對比,網絡開銷容易形成瓶頸

那麼如何在繼承優點的情況下解決缺點喃?

這就涉及到共享內存的概念了。利用本地內存進行解決。那麼關鍵的問題是如何把redis中的數據同步到每個JVM當中喃?這就涉及到了事件通知了,這裏有幾種選擇(1)MQ,如果過期時間較長,且必須保證安全性,那麼這個時候選擇MQ作爲事件的通知選擇非常不錯。(2)redis的pub/sub模式,輕量級

當然這個地方也有一個缺點。就是完全依靠了內存,假設這個時候需要重啓服務器了,那麼之前的token也就不再了。

所以需要提供一種彌補機制,那麼這個時候,我會選擇把數據備份一份給redis或者數據庫,每次重啓的時候就會去拉取到每個JVM當中。這樣就能解決網絡開銷的問題了。

那麼針對(3)這個問題,比較複雜,需要結合多種情況考慮

(1)在APP下,首先,你登錄的時候,我會推送消息給之前的機器,讓他幫你強制下線。然後就是處理JWT

可以在JWT中保存{"userId":1,"version":1,"app":"appId"}這樣的流程就和上面一樣了

(2)在純web下,那麼就只能攔截掉

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