JWT(JSON Web Token) 是一種開放標準(RFC 7519),用于在各方之間安全地傳輸信息作為緊湊且自包含的 JSON 對象。它被廣泛用于身份驗證(Authentication)和授權(Authorization),是現代 Web 開發中替代傳統 Session-Cookie 方案的流行技術。
核心結構:三部分拼接
JWT 由三部分組成,用 .
分隔:
Header.Payload.Signature
示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0IiwibmFtZSI6IkpvaG4iLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
1. Header(頭部)
- 作用:聲明令牌類型和簽名算法。
- 示例:
{"alg": "HS256", // 簽名算法(如 HS256、RS256)"typ": "JWT" // 令牌類型 }
- Base64Url 編碼 → 生成第一部分。
2. Payload(負載)
- 作用:攜帶實際數據(如用戶 ID、權限、過期時間)。
- 包含三類聲明:
- 預定義聲明(Registered Claims):標準字段(非強制)
iss
(簽發者)、exp
(過期時間)、sub
(主題)、aud
(受眾)等。 - 公開聲明(Public Claims):自定義公開字段(需避免沖突)。
- 私有聲明(Private Claims):雙方約定的自定義數據。
- 預定義聲明(Registered Claims):標準字段(非強制)
- 示例:
{"sub": "1234567890", // 用戶 ID"name": "Alice","admin": true,"iat": 1516239022 // 簽發時間 }
- Base64Url 編碼 → 生成第二部分。
3. Signature(簽名)
- 作用:驗證令牌完整性和來源可信性。
- 生成公式:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secretKey )
- 關鍵點:
- 使用 Header 指定的算法(如 HS256)和密鑰生成。
- 防篡改:任何對 Header 或 Payload 的修改都會導致簽名驗證失敗。
工作流程:身份驗證場景
關鍵特性
特性 | 說明 |
---|---|
無狀態(Stateless) | 服務端無需存儲會話信息,減輕數據庫壓力。 |
跨域友好 | 可放在 HTTP Header 或 URL 中,不受同源策略限制(與 Cookie 不同)。 |
自包含(Self-contained) | Payload 可直接解析出用戶信息,減少查詢次數。 |
可擴展性 | 自定義 Payload 添加業務數據(如用戶角色、權限列表)。 |
安全注意事項
-
敏感信息泄露
問題:Payload 僅 Base64 編碼(非加密),可被解碼查看。
解決:- 避免在 Payload 存儲密碼、銀行卡號等敏感數據。
- 敏感數據需加密后再放入 Payload。
-
簽名算法安全
- 禁用
"alg": "none"
:防止攻擊者繞過簽名驗證。 - 推薦強算法:如
HS256
(對稱)或RS256
(非對稱)。
- 禁用
-
密鑰管理
- HS256:密鑰需足夠復雜(長度 >32 字符),并在服務端安全存儲。
- RS256:私鑰嚴格保密,公鑰用于驗證(更安全)。
-
令牌過期
- 必設
exp
(過期時間),縮短攻擊窗口期(建議 15-30 分鐘)。
- 必設
-
令牌吊銷問題
難點:JWT 天然無狀態,無法中途廢止(除非等待過期)。
解決方案:- 維護令牌黑名單(需犧牲無狀態性)。
- 設置短有效期 + 使用 Refresh Token 機制(見下圖)。
最佳實踐:Access Token + Refresh Token
- Access Token:短有效期(如 15 分鐘),用于請求資源。
- Refresh Token:長有效期(如 7 天),存儲于數據庫,用于獲取新 Access Token。
代碼示例:Node.js 生成/驗證 JWT
const jwt = require('jsonwebtoken');// 生成 JWT(HS256 對稱算法)
const payload = { userId: "123", role: "admin" };
const secret = "your-strong-secret"; // 密鑰
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
console.log("Generated Token:", token);// 驗證 JWT
jwt.verify(token, secret, (err, decoded) => {if (err) console.error("驗證失敗:", err.message);else console.log("Decoded Payload:", decoded); // { userId: '123', role: 'admin', iat: ..., exp: ... }
});
適用場景 vs 不適用場景
適用場景 | 不適用場景 |
---|---|
無狀態 API 認證 | 需要即時吊銷令牌的系統 |
微服務間安全通信 | 傳輸大量敏感數據 |
單點登錄(SSO) | 客戶端無法安全存儲令牌的場景 |
移動端/前后端分離應用 |
調試工具
- 在線解析:https://jwt.io
(可查看 Header/Payload,但勿泄露真實 Token)
總結
- JWT 本質:
Base64(Header).Base64(Payload).Signature
。 - 核心價值:無狀態、跨域友好、自包含。
- 安全鐵律:強簽名算法、短有效期、避免敏感數據、密鑰嚴格保護。
- 進階方案:Access Token + Refresh Token 平衡安全性與用戶體驗。
理解 JWT 的機制和安全實踐,是構建現代分布式系統的必備技能。