跳轉到

JWT Stateless Design at Scale with Forced Logout Gaps

概念概覽

設計意圖(非漏洞)

核心知識

設計意圖(非漏洞)

ValidateToken 不查帳號狀態是刻意設計,原因:1M CCU / 500K RPS 下,每個請求查 DB 或 Redis 在技術上不可行。stateless 驗證只驗 JWT 簽名與 TTL(1h),這是效能與安全的刻意 tradeoff,不是遺漏。

前端持有有效 refresh token 期間,即使 device record 刪除或 Redis refresh token 撤銷,access JWT(1h TTL)仍然有效 — 這是設計行為,最多有 1h 的 revoke 延遲視窗。

現有強制登出缺口清單

缺口 現況 影響
Admin RPC 入口 RevokeAccountTokens() 存在但無 gRPC endpoint 暴露 Ban 操作無法立即撤銷 token
Ban hook player.ban 狀態變更時未自動呼叫 RevokeAccountTokens() Ban 後玩家仍可用舊 token 繼續遊戲
Force logout push gRPC Stream / Redis Pub/Sub 機制未實作 Game Server 無法主動關閉 WebSocket

Phase 3 補齊路徑

1. ForceLogoutAccount admin gRPC RPC → 暴露 RevokeAccountTokens()
2. player.ban 狀態變更 hook → 自動呼叫 RevokeAccountTokens()
3. Redis Pub/Sub → Game Server 訂閱 → 主動關閉 WebSocket

即使實作上述機制,access JWT 的 1h TTL 窗口無法完全消除,除非改為 stateful(在 500K RPS 下不可行)。

經驗教訓

  • stateless JWT 的 revoke 延遲是效能設計的必然代價,不應誤判為安全漏洞

  • RevokeAccountTokens() 存在但沒有暴露入口,是典型的「功能實作了但無法被觸發」的架構缺口

  • 強制登出需要三個環節同時到位:撤銷 token、關閉現有連線、阻止 refresh — 缺任何一環都不完整

常見陷阱

  • 把 stateless JWT 不查帳號狀態誤判為 P0 安全漏洞,浪費 sprint 資源

  • 只實作 RevokeAccountTokens() 但不加 ban hook → ban 操作需要手動呼叫 RPC,容易被遺漏

  • 只撤銷 refresh token 但不關閉 WebSocket → 玩家仍在線上繼續遊戲直到斷線重連

相關概念

相關視角

以下頁面與本概念共享主題,但從不同角度切入。保留獨立視角同時提供交叉參考:

來源 Sessions

日期 Session 貢獻摘要

| 2026-04-02 | d088842d-abec-48fc-8a1a-779a5f74e05d | 釐清高 CCU 環境下 stateless JWT 的設計意圖,並系統性列出強制登出機制的現有缺口與 Phase 3 補齊清單 |


本概念頁面由 Semi-Brain Wiki 系統自動維護

最後更新: 2026-04-02