什麼是 JWT?
JWT全名為 JSON Web Token,是一種用於安全傳遞資訊的標準。
為什麼會需要 JWT?
假設今天我們有一個網站,使用者登入後想查看自己的個人資料。
初次登入時,流程非常簡單,只需要在 Client 端打 POST /login API,輸入帳號密碼,伺服器驗證成功後,使用者就成功進入系統了。
但有個問題:之後每一次 API Request,Server 要怎麼知道這是同一位使用者?
如果每次都重新輸入帳號密碼,不但效率差,也會造成很差的使用體驗。
因此,我們就會需要一種登入之後,可以證明自己身份的方法。
傳統 Session 驗證
早期的網站通常使用 Session。
使用者初次成功登入系統後,Server 建立 Session,並回傳 Cookie,
之後每一次請求:
Cookie:
SessionID=ABC123
Server 透過 Session ID 找到 ABC123 所指的使用者,就可以知道「這位使用者已經登入。」
這種方式就是傳統 MVC 網站最常見的做法。
但隨著前後端分離逐漸普及,如果仍然使用 Session,就會出現以下的問題:
- 擴充性較差。
- Server 必須保存所有使用者的 Session。
- 多台 Server 時,需要共享 Session。
因此,REST API 更傾向採用 Stateless 的設計。
也就是 Server 不需要記住任何登入資訊。
JWT 就是用來解決這個問題的方案。
JWT 最常見的用途包括:
- 使用者登入驗證
- API 身份驗證
- 微服務之間傳遞身份資訊
登入成功後,Server 不會保存 Session,而是產生一個 JWT 並回傳給 Client。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
之後每一次 Request,Client 只要帶著這個 Token 即可。
例如:
GET /profile
Authorization: Bearer eyJhbGc...
Server 驗證 Token 後,就知道是哪位使用者。
JWT 的內部構造
JWT 一共由三個部分組成:
Header.Payload.Signature
三個部分之間以 . 隔開。
以下我們有一段 JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqZXJlbXkiLCJyb2xlIjoiVVNFUiIsImV4cCI6MTc1MzYwMDAwMH0.xxxxxxxxxxxxxxxx
可以直接貼上到 JWT 官方的 Decoder,可以看到 decode 結果如下圖

Header
首先是 Header 的部分,Header 描述 JWT 的基本資訊。
例如:
{
"alg": "HS256",
"typ": "JWT"
}
代表:
- typ:JWT
- alg:使用 HS256 演算法進行簽章
通常 Header 不需要自行修改。
Payload
接下來是 Payload,用來存放資料,也稱為 Claims。
例如:
{
"sub":"jeremy",
"role":"USER",
"exp":1753600000
}
常見欄位包括:
| 欄位 | 說明 |
|---|---|
| sub | 使用者身份 |
| role | 使用者權限 |
| exp | Token 到期時間 |
| iat | 發行時間 |
你也可以加入自己的資料。
不過,Payload 並沒有加密,只經過 Base64 編碼。
任何拿到 JWT 的人,都可以解碼查看 Payload,在實作時,不要把機敏資訊存進 Payload。
Signature
最後是 Signature,Signature 是 JWT 最重要的部分。
它可以確保兩件事:
- Token 沒有被修改
- Token 真的是 Server 發出的
裡面包含 Service 的 Secret Key,因此如果有人偷偷修改 Payload,如原本:
role = USER
改成:
role = ADMIN
由於攻擊者不知道 Server 的 Secret Key,因此無法重新產生正確的 Signature。
當 Server 驗證 Token 時就會失敗,回傳 401 Unauthorized。
JWT 驗證流程
簡單介紹完 JWT 的組成後,驗證流程可以以下步驟表示:
- Client 端發送登入請求給 Server
- Server 驗證帳號密碼
- 若成功,Server 就會建立並回傳 JWT 給 Client
- Client 保存 Token
- 通常存在Memory、HttpOnly Cookie 或 Local Storage(需小心 XSS 攻擊)
- 每次呼叫 API 都附帶上 Token
- Server 收到 API Request,便會驗證 JWT
Java SpringBoot 實作
了解 JWT 的運作原理後,接著來看看在 Spring Boot 中是如何建立 JWT 的。
實務上,JWT 通常會封裝在一個 JwtService 中,當使用者成功登入、帳號密碼驗證完成後,便會呼叫 generateToken() 方法建立 JWT,再回傳給 Client。
以下是一個簡化版的範例:
public String generateToken(String username) {
return Jwts.builder()
.subject(username)
.claim("role", "USER")
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + 3600000))
.signWith(secretKey)
.compact();
}
subject(username):設定 JWT 的主體,通常會存放使用者名稱或使用者 ID。claim("role", "USER"):加入自訂資訊(Claim),例如角色或權限。issuedAt():設定 Token 的發行時間。expiration():設定 Token 的有效期限,此範例為 1 小時。signWith(secretKey):使用 Server 的 Secret Key 對 JWT 進行簽章,避免 Token 遭到竄改。compact():將 Header、Payload 與 Signature 組合成最終的 JWT 字串。
如果登入的使用者是 jeremy:
String token = generateToken("jeremy");
就會產生一段類似下面的 JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
接著,Server 會將這個 Token 回傳給 Client。之後每次呼叫 API 時,Client 只需要將 JWT 放在 HTTP Header 中即可:
GET /profile
Authorization: Bearer eyJhbGc...
Server 收到請求後,便會驗證 JWT 是否有效,例如檢查 Signature 是否正確、Token 是否已過期,以及解析出其中的使用者資訊。若驗證成功,就代表這次請求是由合法且已登入的使用者發送。
在實務上,Spring Boot 通常會搭配 Spring Security 使用,並將 JWT 的建立與驗證封裝在 JwtService 中。登入成功時由 JwtService 產生 Token;後續每次 API Request,則由 Spring Security 負責驗證 JWT,再決定是否允許存取受保護的資源。
JWT 的優點
JWT 能夠成為現代 API 身份驗證的主流方案,主要有以下幾個優點:
- Stateless(無狀態):Server 不需要保存每位使用者的登入資訊。
- 適合 REST API:每個 Request 都能獨立完成驗證。
- 容易水平擴充:多台 Server 不需要同步 Session。
- 適合微服務:不同服務可以共享同一個 Token。
JWT 的缺點
JWT 雖然方便,但也有一些限制:
- 無法輕易讓 Token 提前失效。
- Token 一旦外洩,在過期前都可能被使用。
- Header 會比 Session Cookie 更長。
- Secret Key 必須妥善保存。
因此,實務上通常會搭配短效 Access Token 和 Refresh Token 來降低 Token 外洩帶來的風險。
Access Token:有效時間較短(例如 15 分鐘),每次 API Request 都會攜帶。
Refresh Token:有效時間較長(例如 7 天),當 Access Token 過期時,可用來取得新的 Access Token,而不需要重新登入。
JWT 與 Session 比較
| JWT | Session |
|---|---|
| Server 不保存登入資訊 | Server 保存 Session |
| Stateless | Stateful |
| 適合 REST API | 適合傳統 Web |
| 易於水平擴充 | 多台 Server 需共享 Session |
| 常用於前後端分離的專案 | 常見於 MVC 專案 |
結語
一開始會接觸到 JWT,也是因為在設計前後端分離的全端專案時,一直思考著什麼樣的驗證方式才最適合自己的系統。
剛開始,我也曾嘗試過較簡單的驗證方式,如 HTTP Basic Auth,希望能快速完成登入功能。然而,隨著系統加入更多 API,以及開始思考前後端分離、權限管理和後續的擴充性,才發現這些方式在實務上都有一定的限制。
深入了解後,我才開始接觸 JWT。它最大的特色,是能夠讓 Server 在無狀態的情況下驗證使用者身份的機制。也因為如此,它成為現代 REST API 和前後端分離架構中最常見的身份驗證方案之一。


