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 的價值。
點擊複製文章連結