自動刷新JWT解決方案
背景
在前后分離場景下,越來越多的項目使用jwt token作為接口的安全機制,但存在jwt過期后,用戶無法直接感知,假如在用戶操作頁面期間,突然提示登錄,則體驗很不友好,所以就有了token自動刷新需求
但是這個自動刷新方案,基本都離不開服務端狀態存儲,JWT推出思想是:去中心化,無狀態化,所以有所違背
類似這樣的業務,有阿里雲首頁,沒有做token刷新令牌維護,但是符合對應的思想
解決方案
方案一:前端控制檢測token,無感知刷新
用戶登錄成功的時候,一次性給他兩個Token,分別為AccessToken和RefreshToken
AccessToken有效期較短,比如1天或者5天,用於正常請求
RefreshToken有效期可以設置長一些,例如10天、20天,作為刷新AccessToken的憑證
刷新方案:當AccessToken即將過期的時候,例如提前30分鍾,客戶端利用RefreshToken請求指定的API獲取新的AccessToken並更新本地存儲中的AccessToken
核心邏輯
1、登錄成功后,jwt生成AccessToken; UUID生成RefreshToken並存儲在服務端redis中,設置過期時間
2、接口返回3個字段AccessToken/RefreshToken/訪問令牌過期時間戳
3、由於RefreshToken存儲在服務端redis中,假如這個RefreshToken也過期,則提示重新登錄;
小伙伴的疑問:RefreshToken有效期那么長,和直接將AccessToken的有效期延長有什么區別
答:RefreshToken不像AccessToken那樣在大多數請求中都被使用,主要是本地檢測accessToken快過期的時候才使用,
一般本地存儲的時候,也不叫refreshToken,前端可以取個別名,混淆代碼讓攻擊者不能直接識別這個就是刷新令牌。保證自動刷新的前提下,使用較少的查庫次數,防止設置JWT過長的過期時間,對於單端出登錄也有一定的拒絕能力,即無法刷新AccessToken。
缺點:前端每次請求需要判斷token距離過期時間
優點:后端壓力小,代碼邏輯改動不大
后端存儲判斷過期時間
后端存儲AccessToken,每次請求過來都判斷是否要過期,如果快要過期則重新生成新的token,並返回給前端重新存儲,比如距離1天就過期的情況,如果用戶訪問對應的接口則會更新,但假如沒訪問則token已經過期則需要重新登錄
優點:前端改動小,只需要存儲響應http頭里面是否有新的令牌產生,有的話就重新存儲
缺點:后端實現復雜,且泄露后容易存在一直保活狀態,且前端會存在並發請求,當並發請求收到多個jwt token時,容易生成多個token混亂使用