JWT 實戰


上一篇我們講解了 JWT 的基本原理和結構 你了解JWT嗎?,接下來我們具體實戰一下!

1. 引入依賴

<!--引入jwt-->
<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>3.4.0</version>
</dependency>

2. 編寫工具類

@Slf4j
public class JwtUtils {

    private static final String SIGN = "!Q@WXDjksWE$";

    /**
     * 生成 Token  header.payload.signature
     */
    public static String getToken(Map<String, String> map) {
        // 指定令牌的過期時間為 7 天
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE, 7);

        // 創建 Jwt builder
        JWTCreator.Builder builder = JWT.create();

        // 循環添加 payload
        map.forEach((k, v) -> builder.withClaim(k, v));

        // 指定過期時間 簽名 指定加密算法和密鑰
        String token = builder.withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(SIGN));
        log.info("token = {}", token);
        return token;
    }

    /**
     * 1)驗證 Token 合法性【簽名一樣,token合法,過期校驗】
     * 2)如果 Token 校驗過程中出現錯誤,直接拋異常
     *  - SignatureVerificationException:    簽名不一致異常
     *  - TokenExpiredException:             令牌過期異常
     *  - AlgorithmMismatchException:	     算法不匹配異常
     *  - InvalidClaimException:	     失效的payload異常
     */
    public static void verify(String token) {
        JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
    }

    /**
     * 獲取 token 中信息【先校驗 token 合法性,然后再拿 token 中信息】
     */
    public static DecodedJWT getTokenInfo(String token) {
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        return verify;
    }

}

3. 測試用例

 

@SpringBootTest
@Slf4j
public class TestJwt {

    @Test
    public void testJwt() {
        /**
         * JWT 中 header 默認就是 {"alg": "HS256", "typ": "JWT"} 一般不做改變
         */
        HashMap<String, Object> map = new HashMap<>();
        // 指定令牌的過期時間為 20s
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, 1000);

        // 獲取令牌
        String token = JWT.create()
                .withHeader(map)
                .withClaim("userId", 21)        // payload
                .withClaim("username", "zhangsan")  // payload
                .withExpiresAt(instance.getTime())           // 指定令牌的過期時間
                .sign(Algorithm.HMAC256("!Q@WXDjksWE$"));    // 簽名,指定加密算法和密鑰

        log.info("token = {}", token);
    }

    @Test
    public void testValid() {
        // 創建驗證對象
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("!Q@WXDjksWE$")).build();

        // 校驗,獲取校驗后的結果對象信息【需要將上一個 test 執行的 token 字符串傳入,進行校驗】
        DecodedJWT verify = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDMzMzU3NzUsInVzZXJJZCI6MjEsInVzZXJuYW1lIjoiemhhbmdzYW4ifQ.
bLzXG8-QpcwmQSEBEtkoZVBySG2XO5I462fFwTN8MLQ"); log.info("header = {}", verify.getHeader()); log.info("userId = {}, usernmae = {}", verify.getClaims().get("userId").asInt(), verify.getClaims().get("username").asString()); log.info("過期時間 = {}", verify.getExpiresAt()); } }

4. 執行結果

 

 5. 總結

  1)JWT (Json Web Token) 令牌格式:【token = head.payload.signature】

  2)校驗Token順序:a. 校驗簽名算法是否一樣; b. 校驗簽名是否一樣【即:head patload secret 是否一樣】;c. 校驗Token是否有效【前后是否一致 equals】;d. 校驗Token是否過期。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM