WeHelp
JWT 真的安全嗎?很多人以為 JWT 是加密的
2026-06-12 15:52:15
# JWT 真的安全嗎?很多人以為 JWT 是加密的 現在許多網站登入後都會使用 JWT(JSON Web Token)作為身分驗證機制。 但有一個很常見的誤解: > JWT 不是加密技術。 很多新人工程師第一次接觸 JWT 時,以為只要把資料放進 JWT,就沒有人看得到內容。 事實上並不是這樣。 --- ## JWT 長什麼樣子? 一個 JWT 通常會長這樣: ```text xxxxx.yyyyy.zzzzz ``` 總共分成三段: ```text Header.Payload.Signature ``` 例如: ```text eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJ1c2VySWQiOjEyMywiYWNjb3VudCI6InRlc3QxMjMiLCJyb2xlIjoiTWVtYmVyIn0 . j7T1PjD8zH2.... ``` --- ## 第一段:Header Header 用來描述 JWT 的資訊。 例如: ```json { "alg": "HS256", "typ": "JWT" } ``` 表示: * 使用 HS256 演算法 * 類型是 JWT --- ## 第二段:Payload Payload 通常存放使用者資訊。 例如: ```json { "userId": 123, "account": "test123", "role": "Member" } ``` 這也是很多人誤解的地方。 因為: > Payload 並沒有加密。 JWT 只是將資料進行 Base64Url 編碼。 任何取得 Token 的人,都可以看到裡面的內容。 甚至直接到 jwt.io 就能解析。 因此: ```text 不要把密碼 不要把信用卡資訊 不要把身分證字號 不要把敏感個資 放進 JWT ``` JWT 的 Payload 應該只存放必要資訊。 --- ## 第三段:Signature JWT 真正重要的其實是 Signature。 例如: ```text HMACSHA256( Header + Payload, SecretKey ) ``` 伺服器會使用密鑰(Secret Key)產生簽章。 當 JWT 傳回伺服器時, 系統會再次計算 Signature。 如果結果不一致: ```text Token 已被竄改 ``` 就會直接驗證失敗。 因此: > JWT 的重點不是隱藏資料,而是防止資料被修改。 --- ## JWT 通常怎麼傳輸? 最常見的方式是透過 HTTP Header: ```http Authorization: Bearer eyJhbGc... ``` 前端登入成功後: ```text 帳號密碼 ↓ 登入 API ↓ 取得 JWT ↓ 後續請求帶上 JWT ``` 伺服器便能知道目前是哪位使用者。 --- ## JWT 有效期限的重要性 JWT 通常會設定過期時間: ```json { "exp": 1749999999 } ``` 例如: * 15 分鐘 * 30 分鐘 * 1 小時 避免 Token 長時間有效。 即使 Token 外洩,也能降低風險。 --- ## 為什麼還需要 Refresh Token? 如果 JWT 很快過期: ```text 15 分鐘 ``` 使用者可能一直被迫重新登入。 因此實務上通常會搭配: * Access Token * Refresh Token 架構如下: ```text 登入 ↓ Access Token(15分鐘) Refresh Token(7天) ``` 當 Access Token 過期: ```text 前端 ↓ 使用 Refresh Token ↓ 取得新的 Access Token ``` 使用者不需要重新登入。 --- ## Refresh Token 為什麼常放 Cookie? 許多系統會將: ```text Refresh Token ``` 存放在: ```text HttpOnly Cookie ``` 原因是: JavaScript 無法直接讀取 HttpOnly Cookie。 即使網站發生 XSS 攻擊, 攻擊者也較難直接取得 Refresh Token。 因此: ```text Access Token ↓ Header Refresh Token ↓ HttpOnly Cookie ``` 是目前很常見的做法。 --- ## 前後端分離要注意什麼? 如果前端與 API 位於不同網域: 例如: ```text app.example.com api.example.com ``` 或: ```text localhost:3000 localhost:5000 ``` 則需要額外設定: * CORS * Access-Control-Allow-Credentials * Cookie SameSite * Cookie Secure 否則瀏覽器可能不會自動攜帶 Cookie。 很多開發者第一次實作 Refresh Token 時, 卡關的其實不是 JWT, 而是 Cookie 與跨網域設定。 --- ## 結語 很多人以為 JWT 是加密技術。 但實際上: * Header 可以看 * Payload 可以看 * Signature 才是驗證重點 JWT 的目的不是隱藏資料,而是驗證資料是否遭到竄改。 因此在設計 JWT 時: * 不要放敏感資訊 * 設定合理過期時間 * 搭配 Refresh Token * 妥善保護 Secret Key 才能真正發揮 JWT 的價值。