• 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是否过期。

  • 相关阅读:
    ELK扫盲及搭建
    重构支付接口(二)重构方案
    重构支付接口(一)支付接口存在的问题
    redis的持久化(RDB与AOF)
    死锁、活锁、性能问题
    Android控件_RecycleView+CarView+Palette联合应用
    窗体间传值 ,子窗体传给父窗体
    【Android-自定义控件】 漂亮的Toast
    【Android-关闭所有Activity】关闭activity之前的所有activity,重启actibity
    【Android-自定义控件】SwipeRefreshDemo 下拉刷新,上拉加载
  • 原文地址:https://www.cnblogs.com/blogtech/p/13857208.html
Copyright © 2020-2023  润新知