這篇文章記錄一次 JWT 雙票(AT/RT)治理的實際經驗。
我們想回答的問題很簡單:當刷新令牌在異常情境下被重放時,系統能不能快速發現並收口。
說明:本文的網域、IP、帳號識別、會話識別與日誌內容皆為脫敏示例,不對應任何真實生產資料。
系統邊界如下:
- 前端:Web SPA(AT 僅存於記憶體)
- 後端:Go + Gin(鑑權與刷新)
- 會話層:Redis(令牌狀態索引)
- 閘道:HTTPS 反向代理
現象與觸發條件
在一次面向設備接入與 Web 應用認證鏈路的復現測試中,我們模擬了「舊 RT 被攔截後重複提交」的極端情境。
舊方案雖然有 AT/RT 分層,但刷新路徑缺少完整狀態約束,舊 RT 在短時間並發下仍可能被利用。
脫敏事件樣式如下:
{
"event": "auth.refresh.reuse_detected",
"user_id_masked": "u-***39",
"session_id": "s-***b1",
"ip_masked": "10.**.**.21",
"action": "session_revoked"
}
排查與改造策略:保留 AT 無狀態,強化 RT 治理
我們沒有改動雙票結構,而是針對 RT 刷新主路徑補齊治理能力,目標是可撤銷、可審計、可回收。
第一層:維持清楚的令牌分工
- AT 負責高頻請求,走
Authorization: Bearer - RT 僅透過 HttpOnly Cookie 傳輸
- AT 校驗維持無狀態,確保效能與擴展性
這樣可以把控制面集中在 RT,不影響 AT 的輕量存取。
第二層:把 RT 刷新收斂為單次可追蹤流程
刷新路徑遵循固定順序:校驗舊 RT -> 簽發新 RT -> 更新 Redis 狀態 -> 失效舊 RT。
Redis Key 模型(脫敏示例):
rt:active:{jti} -> { user_id, session_id, exp } // 核心狀態,TTL 跟隨 RT 到期
rt:session:{session_id} -> Set<jti> // 冗餘索引,用於會話級一鍵清理
rt:deny:{jti} -> 1 (TTL=剩餘有效期) // 黑名單,攔截被重放的舊票據
user:sessions:{user_id} -> Set<session_id> // 使用者級管控,支援「踢出其他裝置」
對應約束:
- 同一 RT 僅允許成功刷新一次
- 新 RT 生效後,舊 RT 立即進入 deny 清單
- 刷新流程加入短時鎖,避免並發競態
並發防抖設計(結果復用視窗)
現代 SPA 常會同時送出多個請求,若沒有防抖協調,舊 RT 可能在同一時間觸發多次刷新,進而讓合法請求被誤判為重放。為此我們設計了 5 秒復用視窗:
- 第一個請求先拿鎖並完成 RT 輪換
- 輪換後的 AT/RT 會快取 5 秒
- 同 key 的併發請求在 5 秒內直接復用同一組 AT/RT,不再二次輪換
- 視窗到期後,恢復嚴格單次輪換策略
第三層:重放事件的處置方式
一旦識別 RT 重放,系統會對相關會話執行失效、寫入審計事件,並引導前端回到登入流程。
重點不是硬撐原會話,而是盡快終止風險會話。
第四層:讓登出與高風險操作觸發服務端吊銷
以下操作統一接入會話失效流程:
- 使用者主動登出
- 管理員重設密碼
- 使用者狀態切換為鎖定或停用
也就是說,登出不再只是刪除瀏覽器 Cookie,而是服務端狀態同步失效。
根因總結
這次問題本質上是治理深度不足,而非單一程式錯誤:
- 早期實作以簽發與驗簽為主,對令牌生命週期覆蓋不足。
- 會話狀態能力雖已預留,但未完整接入刷新主鏈路。
改造後的收益
這次治理後,鏈路上的變化主要有三點:
- 會話可在服務端快速撤銷
- RT 重放可被識別並追蹤
- 安全事件可按使用者與會話維度快速定位
對使用者體驗影響可控:正常路徑維持無感刷新,異常路徑回到重新登入。
過程改進與行動項
1)把令牌生命週期校驗納入發版檢查
發版前固定校驗:
- RT 單次使用驗證
- 刷新並發一致性驗證
- 登出/重設密碼後的會話失效驗證
2)統一安全審計欄位
審計日誌統一採用脫敏欄位:user_id_masked、session_id、jti_prefix、ip_masked、ua_hash、risk_level。
3)固定進行重放演練
每月執行一次 RT 重放演練,持續驗證告警、失效與回收流程是否正常。
後續可選增強項
目前方案已建立 Redis 會話撤銷鏈路與並發防重放機制。Refresh 流程已能即時校驗使用者狀態,帳號一旦鎖定或停用,會立即阻斷新票據簽發。
如果後續需要覆蓋更複雜的 Token 劫持場景,可再加入以下控制:
- 環境指紋比對:可引入 IP 段與 UA Hash 組合校驗,在 RT 出現異常地域跳變時觸發更嚴格的票據失效與附加驗證。
- 規則校正:在複雜網路環境下,需先驗證 4G/5G 頻繁切網、出口漂移等合法抖動,再決定是否啟用更嚴格的判定規則。
結語
認證安全的關注點之一,是異常發生後的收口能力。
這次改造補上了 RT 刷新鏈路中的會話撤銷與並發防重放控制。