JWT

JWT

1. 什麼是 JWT?

JSON Web Token (JWT) 是一種開放標準(RFC 7519),定義了一種簡潔(compact)且自包含(self-contained)的方式,用於在各方之間安全地傳遞資訊作為 JSON 物件。JWT 透過數位簽章確保資料的完整性和真實性,可以使用對稱金鑰(HMAC)或非對稱金鑰(RSA、ECDSA)進行簽名。

關鍵特性

2. JWT 的結構

JWT 由三個部分組成,使用點(.)分隔:

HEADER.PAYLOAD.SIGNATURE

2.1 Header(標頭)

Header 描述 JWT 的元資訊,通常包含:

{
  "alg": "HS256",  // 簽名演算法
  "typ": "JWT"     // Token 類型
}

主要欄位:

2.2 Payload(負載)

Payload 包含聲明(Claims),分為三類:

註冊聲明(Registered Claims):

公開聲明(Public Claims):在 IANA 註冊或使用防衝突名稱

私有聲明(Private Claims):自定義的應用程式特定資訊

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022
}

2.3 Signature(簽名) Signature 用於驗證 JWT 的完整性和真實性:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

3. JWT 的運作流程

  1. 使用者登入:提供身份驗證資訊

  2. 伺服器驗證:驗證使用者身份

  3. 簽發 JWT:伺服器生成並回傳 JWT

  4. 攜帶 Token:客戶端在後續請求中攜帶 JWT

  5. 驗證授權:伺服器驗證 JWT 的有效性並授權存取

Authorization: Bearer <token>

這種方式實現了無狀態認證(Stateless Authentication),伺服器無需儲存 session 資訊。

4. 使用場景

4.1 授權(Authorization)

4.2 單點登入(SSO)

4.3 資訊交換

5. 簽名演算法

5.1 HMAC 演算法

特點:使用共享密鑰,任何擁有密鑰的一方都可以驗證和生成簽名。

5.2 RSA 演算法

特點:使用非對稱密鑰,私鑰簽名,公鑰驗證,實現一對多的安全分發。

5.3 ECDSA 演算法

6. 安全考量

6.1 儲存安全

6.2 演算法安全

6.3 資料敏感性

6.4 生命週期管理

7. 優點與缺點

7.1 優點

7.2 缺點

8. 實作範例

8.1 Node.js 範例

const jwt = require('jsonwebtoken');
const secret = 'your-256-bit-secret';

// 簽發 JWT
const payload = { 
  sub: '1234567890', 
  name: 'John Doe',
  iat: Math.floor(Date.now() / 1000)
};

const token = jwt.sign(payload, secret, { 
  algorithm: 'HS256', 
  expiresIn: '1h' 
});

// 驗證 JWT
try {
  const decoded = jwt.verify(token, secret, { 
    algorithms: ['HS256'] 
  });
  console.log('Decoded payload:', decoded);
} catch (err) {
  console.error('Invalid token:', err.message);
}

8.2 Ruby 範例

require 'json'
require 'base64'
require 'openssl'

# 建立 header 和 payload
header = { alg: "HS256", typ: "JWT" }
payload = { sub: "1234567890", name: "John Doe", admin: true }

# Base64 編碼
encoded_header = Base64.urlsafe_encode64(JSON(header))
encoded_payload = Base64.urlsafe_encode64(JSON(payload))

# 生成簽名
digest = OpenSSL::Digest::SHA256.new
data = "#{encoded_header}.#{encoded_payload}"
signature = OpenSSL::HMAC.digest(digest, 'secret', data)
encoded_signature = Base64.urlsafe_encode64(signature).gsub('=', '')

# 完整的 JWT
jwt_token = "#{encoded_header}.#{encoded_payload}.#{encoded_signature}"
puts jwt_token

9. JWT 的擴展規範

9.1 JSON Web Signature (JWS)

9.2 JSON Web Encryption (JWE)

9.3 JSON Web Key (JWK)

10. 最佳實踐

10.1 設計原則

10.2 實作建議

10.3 監控與日誌

11. 總結

JWT 是一種強大且靈活的身份驗證和授權機制,特別適合現代的分散式系統架構。雖然存在一些安全考量,但透過適當的實作和安全措施,JWT 能夠提供安全、高效的身份驗證解決方案。

在選擇 JWT 時,需要根據具體的應用場景權衡其優缺點,並確保遵循最佳實踐以最大化安全性和效能。對於需要即時撤銷功能的應用,可能需要結合其他技術(如 Redis 黑名單)來補強 JWT 的限制。

參考