JWT token 過期續簽的問題想法
-
服務端保存簽發的token,進行失效判斷,使用Redis保存
-
如果服務端,不保存token
-
客戶端解析 token中 payload的數據,添加失效時間,再失效時間之前再次進行簽到
-
客戶端 保存兩個 token:access_token、refresh_token
refresh_token 的有效期比 access_token 長,成倍數2倍,當access_token 失效后,使用refresh_token去重新進行續簽
如果refresh_token也失效,需要重新登錄
當refresh_token有效的時候,進行續簽的時候,需要對已經失效的access_token進行校驗,校驗access_token過期時間必須最近的,不能太遠
access_token中的payload存儲用戶相關的申明信息
refresh_token中的payload中只保存過期時間,或者與access_token有關的一些的信息
refresh_token是對access_token服務的,不能去替代,不然就失去了原本的意義了
那么一般的設計就很清楚了 token(jwt) + refresh_token , 因為token(jwt)自己內含全部的驗證數據,如果丟失就麻煩大了,所以有效期一定要盡可能短一些,比如5分鍾。過期后,就用refresh_token 去刷新一下,獲取新的token。 (refresh_token 因為是偶爾使用一次,用在MYSQL里查庫或者redis,都比較穩當了)
---------------------------
補充:為什么要refresh_token去刷新,是因為token頻繁傳輸,容易被竊取,refresh_toke則只有刷新token的時候使用一次,用完一次就報廢了
存在的問題:token不能作廢,只能過期,保存在服務端的時候,可以定期的去清理token,不在服務端的token都可以不認
-
個人覺得的使用范圍
- 臨時令牌(只簽發不續簽)
- 永久令牌(長期有效,丟失只能屏蔽掉加密的秘鑰)
接口資源保護,只有有令牌才能訪問
場景舉例:類似於 gihtub或者碼雲,使用令牌向存儲庫中推送文件
網上有人提出了一種思路,
在不用緩存的情況下,可以將 每個用戶的信息和加密令牌使用的秘鑰secret綁定起來,
中間甚至可以加入用戶權限相關信息,具體根據業務決定
那么在注銷或者修改密碼的時候去更新綁定的秘鑰,同時可以再加上更新的時間
用戶id | 登錄秘鑰 | 臨時秘鑰 | 長期秘鑰
登錄秘鑰:會話期間使用,注銷或者修改密碼修改
臨時秘鑰: 適用頒布臨時令牌,修改密碼時重置
長期令牌:適用頒布長期立牌,修改密碼時重置
存在問題,每次都需要去根據用戶id,查數據庫,效率不行,都已經查數據了,不如直接用數據庫的秘鑰作為臨牌
個人想法,可不可以使用
用戶信息中的某個數據 與 一個秘鑰 進行某些運算 可以得到 登錄秘鑰
signature 中需要分成兩部分,JWT簽名 + 用戶個人私鑰,將此部分再使用可逆向解密的算法再次進行加密,作為新的簽名
校驗部分
對前端傳來的 新的簽名先進行解密,拿到用戶個人私鑰與程序的公鑰進行運算,得出jwt加密的秘鑰,再去進行校驗 jwt簽名是否有效
用戶續簽的時候去查數據中用戶的登錄秘鑰,個人私鑰+程序公鑰 = 用戶的登錄秘鑰,每次用戶注銷改密的時候,修改掉登錄秘鑰,更新數據庫
其他
SS0單點登錄
- 多了一個授權中心,中心頒發令牌和存儲頒發了的令牌
- 子系統只認中心頒發的令牌,需要向中心核實令牌真實性
不考慮令牌丟失情況下,可以使用直接續簽的策略
前端定時刷新令牌,后端重新生成令牌給前端
再安全一點,使用雙token