處理 JWT expiration 時,我第一件事是確認 exp 的單位。RFC 7519 的 NumericDate 是 Unix epoch 的秒數,但 JavaScript Date.now() 是毫秒;如果直接比較,結果會完全錯誤。
如果只是要快速看時間狀態,我會用 JWT Expiry Checker 同時查看 iat、nbf、exp 與 active window。
exp 真正代表什麼
例如:
{
"iat": 1789320000,
"exp": 1789323600
}
代表 token 在 exp 時刻之後不應再被接受。這只是一個時間條件,不代表 signature、issuer 或 audience 已經驗證。
JavaScript 最容易犯的錯
錯誤:
Date.now() >= payload.exp
正確做法要把秒轉成毫秒:
const expired = Date.now() >= payload.exp * 1000;
const expiresAt = new Date(payload.exp * 1000);
我也會先確認 exp 真的是 number,而不是字串。
iat、nbf、exp 我會一起看
我把它們畫成時間線:
iat -------- nbf ===== usable window ===== exp
iat:何時發行;nbf:從何時開始可用;exp:何時停止接受。
不是每個 token 都會同時包含三者,但如果有,我會看它們的關係是否合理。
用 exp - iat 看 lifetime
const lifetimeSeconds = payload.exp - payload.iat;
如果 access token 的 lifetime 遠高於產品預期,我會確認 issuer 設定是否錯誤。JWT Security Analyzer 也可以提供 maximum lifetime policy 做 deterministic check。
Clock skew 要小而有意識
分散式系統的 clock 可能差幾秒,因此 verifier 可以有有限度 tolerance。但我不會把 tolerance 調到幾分鐘甚至更長,只為了讓測試通過。
如果「剛發的 token 立刻 expired」,我會檢查:
- issuer/server clock;
- NTP/container clock;
iat、nbf、exp;- seconds vs milliseconds;
- 是否其實拿到 cache 裡的舊 token。
Timezone 只影響顯示方式,不會改變 epoch 比較本身。
沒有 exp 一定 invalid 嗎
標準並沒有規定所有 JWT 都必須有 exp,但 application 可以要求它。
如果 API policy 是「所有 access token 必須有 expiration」,那 missing exp 就應該 fail。這是應用程式 profile 的要求。
Client-side expiration check 不是 security boundary
前端可以先檢查 exp,避免發出明知會失敗的 request,改善 UX。但真正的 resource server 仍要自己驗 expiration。
browser clock 與 client code 都不應成為最終 security authority。
還沒過期卻 401 怎麼辦
exp 正常只代表時間沒有失敗。我還會看:
- signature;
iss;aud;nbf;- token type;
- scope/role;
- JWKS rotation/cache。
完整排查見 JWT 401 Unauthorized。
已過期應怎麼處理
我不會修改 payload 的 exp 再重新 Base64URL encode。那會破壞 signature。
正確流程通常是:
- 使用合法 refresh flow 取得新 access token;或
- refresh 不可用/失效時重新 authentication。
我會測哪些 edge cases
exp 在過去 → fail
exp 等於現在 → fail/依 library 規則
exp 在未來 → time check pass
exp 是 string → fail schema/policy
exp missing → 依 required-claim policy
nbf 在未來 → fail
iat 明顯在未來 → investigate/fail policy
production verifier 我會優先使用成熟 JWT library 的時間驗證功能,而不是只靠自己寫幾行 epoch comparison。
我的 exp 檢查清單
exp資料型別正確嗎?- NumericDate 是秒,不是毫秒。
- JavaScript 是否正確
* 1000? iat、nbf與exp關係合理嗎?- issuer/verifier clock 是否同步?
- clock skew 是否有限且明確?
- server 端是否真的 enforcement expiration?
- expiration 通過後是否仍驗 signature、issuer、audience?
我處理 exp 的核心不是把 timestamp 轉成漂亮日期,而是確認 時間單位、token lifecycle 與 verifier policy 三者一致。