在Java中解碼JWT令牌

REST,Security
Remote
0
05:45 AM · Dec 01 ,2025

1. 概述

一個 JSON Web Token (JWT) 常被用於 REST API 安全中。 儘管令牌可以被 Spring Security OAuth 等框架解析,但我們可能希望在自己的代碼中處理令牌。

在本教程中,我們將 解碼並驗證 JWT 的完整性

2. JWT 結構

首先,讓我們理解 JWT 的結構:

  • header
  • payload (通常被稱為 body)
  • signature

簽名是可選的。一個有效的 JWT 可以只包含 header 和 payload 部分。但是,我們使用 signature 部分來驗證 header 和 payload 的內容以進行安全授權

部分以 base64url 編碼的字符串表示,用 period (‘.’) 分隔符分隔。按照設計,任何人都可以解碼 JWT 並讀取 header 和 payload 部分的內容。但是,我們需要訪問用於創建簽名所使用的密鑰,才能驗證令牌的完整性。

通常,JWT 包含用户的“聲明”(claims)。這些聲明代表有關用户的元數據,API 可以使用這些元數據來授予權限或跟蹤提供令牌的用户。解碼令牌允許應用程序使用數據,而驗證允許應用程序信任 JWT 由可信來源生成。

讓我們看看如何在 Java 中解碼和驗證令牌。

3. 解碼 JWT

我們可以使用內置的 Java 函數來解碼令牌。

首先,讓我們將令牌分解為不同的部分:

String[] chunks = token.split("\\.");

請注意,傳遞給 String.split 的正則表達式使用轉義的 ‘.’ 字符,以避免 ‘.’ 表示“任意字符”。

我們的 chunks 數組現在應該包含兩個或三個元素,對應於 JWT 的部分。

接下來,讓我們使用 base64url 解碼器解碼 header 和 payload 部分:

Base64.Decoder decoder = Base64.getUrlDecoder();

String header = new String(decoder.decode(chunks[0]));
String payload = new String(decoder.decode(chunks[1]));

讓我們用一個 JWT(我們可以 在線解碼 進行比較)運行這段代碼:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJhZWxkdW5nIFVzZXIiLCJpYXQiOjE1MTYyMzkwMjJ9.qH7Zj_m3kY69kxhaQXTa-ivIpytKXXjZc1ZSmapZnGE

輸出將提供解碼後的 header 和 payload:

{"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"Baeldung User","iat":1516239022}

如果 JWT 中僅定義了 header 和 payload 部分,我們已經完成了併成功解碼了信息。

4. 驗證 JWT

接下來,我們可以使用簽名部分來驗證頭信息和有效負載的完整性,以確保它們未被修改。

4.1. 依賴項

為了進行驗證,我們可以將 jjwt 添加到我們的 pom.xml 中:


<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.12.3</version>
</dependency>

我們應該注意的是,我們需要這個庫的版本必須從版本 0.7.0 之後。

4.2. 配置簽名算法和密鑰規範

為了開始驗證有效負載和頭信息,我們需要使用原始用於對令牌進行簽名所使用的簽名算法以及密鑰:


SignatureAlgorithm sa = SignatureAlgorithm.HS256;
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), sa.getJcaName());

在這個例子中,我們已經硬編碼了我們的簽名算法為 HS256。但是,我們可以解碼頭信息中的 JSON 並讀取 alg 字段來獲取這個值。

我們還應該注意的是,變量 secretKey 是密鑰的字符串表示形式。我們可能通過其配置或由發出 JWT 的服務提供的 REST API 向我們的應用程序提供此信息。

4.3. 執行驗證

現在我們已經有了簽名算法和密鑰,我們可以開始執行驗證。


JwtParser jwtParser = Jwts.parser()
    .verifyWith(secretKeySpec)
    .build();
try {
    jwtParser.parse(token);
} catch (Exception e) {
    throw new Exception("Could not verify JWT token integrity!", e);
}

讓我們分解一下。

首先,我們創建一個使用選擇的算法和密鑰的 JwtParser。然後我們使用 JwtParser 解析令牌。內部的 parse 方法的實現會生成一個新的簽名並將其與提供的簽名進行比較。如果它們相等,我們已驗證了頭信息和有效負載的完整性。如果拋出任何異常,則意味着令牌無效(它可能是格式錯誤、已過期等)。

5. 結論

在本文中,我們探討了 JWT 的結構以及如何將其解碼為 JSON。

然後,我們使用庫來驗證令牌的完整性,使用其簽名、算法和密鑰。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.