Stories

Detail Return Return

JWT令牌 - Stories Detail

Maven座標

<dependency> 
    <groupId>io.jsonwebtoken</groupId> 
    <artifactId>jjwt</artifactId> 
    <version>${jjwt}</version> 
</dependency>

生成jwt

  • 指定簽名的時候使用的簽名算法

  • SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

  1. 構建 JWT:使用 Jwts.builder() 創建一個 JWT 構建器對象,並進行三項核心設置:

    • 設置自定義聲明:.setClaims(claims) 將用户提供的自定義信息添加到令牌中

    • 設置簽名信息:.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8)) 使用指定算法和密鑰生成簽名

    編碼處理:密鑰在使用前通過 getBytes(StandardCharsets.UTF_8) 轉換為 UTF-8 編碼的字節數組,確保跨平台一致性。

    • 設置過期時間:.setExpiration(exp) 設置令牌的有效期
  2. 生成最終令牌:通過 builder.compact() 方法將構建的 JWT 對象序列化為最終的字符串形式。

/**
 * 生成jwt
 * 使用Hs256算法, 私匙使用固定秘鑰
 *
 * @param secretKey jwt秘鑰
 * @param ttlMillis jwt過期時間(毫秒)
 * @param claims    設置的信息
 * @return
 */
public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
    // 指定簽名的時候使用的簽名算法,也就是header那部分
    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

    // 生成JWT的時間
    long expMillis = System.currentTimeMillis() + ttlMillis;
    Date exp = new Date(expMillis);

    // 設置jwt的body
    JwtBuilder builder = Jwts.builder()
            // 如果有私有聲明,一定要先設置這個自己創建的私有的聲明,這個是給builder的claim賦值,一旦寫在標準的聲明賦值之後,就是覆蓋了那些標準的聲明的
            .setClaims(claims)
            // 設置簽名使用的簽名算法和簽名使用的秘鑰
            .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
            // 設置過期時間
            .setExpiration(exp);

    return builder.compact();
}

解析jwt

  1. 創建解析器: 通過 Jwts.parser() 創建一個 JWT 解析器實例

  2. 設置驗證密鑰: 使用 setSigningKey() 方法設置用於驗證簽名的密鑰,這裏同樣將密鑰轉換為 UTF-8 編碼的字節數組

  3. 解析並驗證令牌: 調用 parseClaimsJws(token) 方法解析令牌,這個方法會自動驗證:

    • 令牌的簽名是否有效(使用提供的密鑰)

    • 令牌是否已過期

    • 令牌的格式是否正確

  4. 獲取聲明信息: 通過 getBody() 方法獲取令牌中包含的所有聲明信息

/**
 * Token解密
 *
 * @param secretKey jwt秘鑰 此秘鑰一定要保留好在服務端, 不能暴露出去, 否則sign就可以被偽造, 如果對接多個客户端建議改造成多個
 * @param token     加密後的token
 * @return
 */
public static Claims parseJWT(String secretKey, String token) {
    // 得到DefaultJwtParser
    Claims claims = Jwts.parser()
            // 設置簽名的秘鑰
            .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
            // 設置需要解析的jwt
            .parseClaimsJws(token).getBody();
    return claims;
}

映射配置

sky:
  jwt:
    # 設置jwt簽名加密時使用的秘鑰
    admin-secret-key: itcast
    # 設置jwt過期時間
    admin-ttl: 7200000
    # 設置前端傳遞過來的令牌名稱
    admin-token-name: token
    # 登錄用户jwt的配置信息
    user-secret-key: itcast
    user-ttl: 7200000
    # 設置前端傳遞過來的令牌名稱
    user-token-name: authentication

創建一個JwtProperties類進行配置映射

@Component
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {

    /**
     * 管理端員工生成jwt令牌相關配置
     */
    private String adminSecretKey;
    private long adminTtl;
    private String adminTokenName;

    /**
     * 用户端微信用户生成jwt令牌相關配置
     */
    private String userSecretKey;
    private long userTtl;
    private String userTokenName;

}

Add a new Comments

Some HTML is okay.