JWT for Java: 詳細解析與實踐

一、什麼是JWT

JSON Web Token(JWT)是一種用於安全傳輸信息的開放標準,基於 JSON 格式定義了一種緊湊且自包含的方式來在各方之間安全地傳輸信息。JWT 可以被用作驗證身份、信息交換的 token。

一個 JWT 由三個部分組成,分別是頭部(Header)、載荷(Payload)和簽名(Signature):

{
  "alg": "HS256",
  "typ": "JWT"
}
.
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
.
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

其中,頭部和載荷都是 JSON 格式,簽名是根據特定演算法生成的字元串,用於驗證 JWT 的可靠性。JWT 的優勢在於它既可以存放認證信息,又可以存放其他的業務信息,而且用戶信息都加密存儲,不需要每次都從資料庫中讀取用戶信息。

二、JWT的使用場景

下面列舉了一些 JWT 的常見使用場景:

  • 用戶身份驗證:用戶登錄後伺服器返回 JWT,客戶端之後訪問其他介面時攜帶 JWT 作為鑒權憑證。
  • 應用程序授權:JWT 用於應用程序內部介面的鑒權授權,例如微服務內部的介面訪問。
  • 密碼重置/郵箱驗證等場景:發送 JWT 至用戶郵箱或者手機,使用 JWT 驗證用戶身份並執行相應的操作。

三、實現JWT in Java

首先,我們需要添加相關依賴:

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-jackson -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

接下來,我們可以創建一個 JWTUtil 來處理操作 JWT:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;

public class JWTUtil {

  /**
   * 根據用戶信息生成 jwt
   */
  public static String generateToken(User user) {
    Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    long nowMillis = System.currentTimeMillis();
    Date now = new Date(nowMillis);

    JwtBuilder builder = Jwts.builder()
        .setId(user.getId())
        .setIssuedAt(now)
        .setSubject(user.getName())
        .setIssuer(user.getName())
        .signWith(key);

    long ttlMillis = 86400000L; //過期時間為1天
    if (ttlMillis >= 0) {
      long expMillis = nowMillis + ttlMillis;
      Date exp = new Date(expMillis);
      builder.setExpiration(exp);
    }

    return builder.compact();
  }

  /**
   * 根據 jwt 解析用戶信息
   */
  public static User parseToken(String token) {
    Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    Claims claims = Jwts.parser()
        .setSigningKey(key)
        .parseClaimsJws(token)
        .getBody();

    User user = new User();
    user.setId(claims.getId());
    user.setName(claims.getSubject());

    return user;
  }
}

四、使用 JWT 進行授權認證

在使用 JWT 進行授權認證時,通常需要將 JWT 存儲在客戶端(如瀏覽器)中,這樣可以在下次訪問時帶上 JWT,從而進行認證。下面是一個使用 JWT 進行授權認證的示例:

@GetMapping("/users/me")
public ResponseEntity currentUser(@RequestHeader(value="Authorization") String token) {
    // 從請求頭中獲取 JWT
    if (token.startsWith("Bearer ")) {
        token = token.substring(7);
    }

    // 驗證 JWT 並獲取用戶信息
    User user = JWTUtil.parseToken(token);
    if (user != null) {
        return ResponseEntity.ok(user);
    }

    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

結語

JWT 是一種非常實用的鑒權方式,它具有跨語言、解耦合等優點。在 Java 中,我們可以使用 jjwt 庫來操作 JWT,可以將其用於介面鑒權、用戶身份認證等場景。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/227756.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-09 16:31
下一篇 2024-12-09 16:31

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Python for循環求1到100的積

    Python中的for循環可以方便地遍歷列表、元組、字典等數據類型。本文將以Python for循環求1到100的積為中心,從多個方面進行詳細闡述。 一、for循環語法 Pytho…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29

發表回復

登錄後才能評論