關於JWT用戶主動注銷、強制登出、忘記密碼、修改密碼的一些思考


JWT(JSON WEB TOKEN)的特點是無狀態,通常用來作為驗證登錄以及鑒權,在這一方面,JWT體現出了他的優點。

然而,如果使用JWT實現,用戶主動注銷、強制登出(禁止登陸)、忘記密碼、修改密碼,JWT續簽等方面的需求,就會讓人頭疼。

按照網上的一些討論,我概括如下:

1、將每一個簽發的JWT保存在REDIS上,當出現上述的需求時,就更新對應的JWT,如果客戶端與REDIS中的不同,那么登錄失敗。

這種方法雖然可以解決上述問題,但是此時JWT似乎變成了有狀態的了,部分失去了JWT的優點。

2、在簽發、鑒別JWT中,不使用公共的秘鑰,而是為每一個賬戶保存一個對應的秘鑰,當客戶端發來請求時,使用秘鑰驗證,如果失敗說明這個JWT已經失效,可以實現上述的功能。

然而,對於每一個請求都需要在數據庫中查找對應的秘鑰,這為服務器增加了負擔。

3、如果用戶主動注銷,或者主動修改密碼,僅僅在客戶端對之前的JWT刪除(此時,如果獲得了之前的JWT仍然可以登錄),似乎不會對安全性帶來影響,因為此時,之前的JWT並沒有被泄露。

 

然而有沒有一種方式可以不使用數據庫來實現上述功能?

這個問題的答案我也不清楚。

不過希望我提供的這一個方案可以給大家一些思路。(如有雷同純屬巧合)

使用JWT的一個原則是盡可能的發揮它無狀態的優點。

一般來說,在Restful的操作中,用戶發生正常操作的概率,遠遠大於上述5個操作。為了充分利用這一點,減少查庫操作,我把上述五個功能分為2個部分

可預知:用戶主動注銷、修改密碼、以及JWT續簽

可預知:服務器在當前請求中,知道當前操作的一個效果是為了失效當前JWT,在這個部分中,服務器清楚地知道需要失效的JWT的實際值。

解決方案:當服務器收到一個可預知的請求時,首先在redis中查詢是否存在當前JWT,如果存在返回false,否則在redis中插入當前jwt,這條數據的失效時間為當前jwt的剩余有效時間。

不可預知:強制登出(禁止登陸)、忘記密碼、

不可預知:服務器在當前請求中,知道當前操作的一個效果是為了失效某個JWT,這個JWT的實際值未知,但是這個JWT所對應的賬戶已知。

解決方案: 解析這個JWT后,得到AppID,timeStamp、查詢redis,如果對應AppID 的timeStamp小於 redis中的timeStamp,返回false,否則在redis中插入當前AppId,與當前時間戳,這條數據的失效時間為JWT生存期。(因為無法得到簽發的JWT剩余時間,只能按照最大時間處理)。

 

上述方法缺點:還是避免不了查庫,但是減少了庫中存放的內容

如果上述方法存在漏洞,歡迎指正。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM