美文网首页
JWT令牌速成

JWT令牌速成

作者: 炒面Z | 来源:发表于2019-04-07 15:41 被阅读0次

    1.jwt令牌是什么

    全称 JSON Web Token,是目前最流行的跨域身份验证解决方案

    2.jwt数据结构

    token分为三部分,header.payload.signatrue. 号分隔

    • header 头文件
    • payload 有效荷载
    • signatrue 签名文件
    • header信息
      如:签名使用的算法HS256,typ属性表示令牌的类型
    {
    "alg": "HS256",
    "typ": "JWT"
    }
    
    • payload有效荷载
      jwt默认提供了以下7个属性设置,也可以自定义属性字段(类似Map中设置)
    默认参数:
    iss:发行人
    exp:到期时间
    sub:主题
    aud:用户
    nbf:在此之前不可用
    iat:发布时间
    jti:JWT ID用于标识该JWT
    
    • 签名哈希
      签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。
    var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload)
    var signature = HMACSHA256(encodedString, 'secret')
    最终解果 : token = base64UrlEncode(header) 
    + '.' + base64UrlEncode(payload) 
    + '.' + signature
    

    代码测试

    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import org.junit.Test;
    
    import java.util.Base64;
    import java.util.Date;
    
    public class JwtTest {
    
    
        /**
         * signature底层原理
         * <p>
         * var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload)<p>
         * var signature = HMACSHA256(encodedString, 'secret')<p>
         * 最终解果 : token = base64UrlEncode(header) + '.' + base64UrlEncode(payload) + '.' + signature<p>
         * demo:  eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIwMDciLCJzdWIiOiJzaHVzbSIsImV4cCI6MTU1NDYyMzc2MiwibmJmIjoxNTU0NzA2NTYyLCJpYXQiOjE1NTQ2MjAxNjIsImlzcyI6Imp1bml0In0.GHyxmrcXzxnAHN8ib2209I48wUpIU1Pyr_-sGDucoMM<p>
         * <p>
         * <p>
         * payload 建议使用参数:<p>
         * iat  jwt的签发时间<p>
         * exp  jwt的过期时间,这个过期时间必须要大于签发时间<p>
         * nbf  定义在什么时间之前,该jwt都是不可用的<p>
         */
        @Test
        public void testJwt() {
            String secret = "loveqq";// 密钥
    
            String token = Jwts.builder().claim("userId", "007")
                    .setSubject("shusm")
                    // exp 有效期设置 - 1h失效
                    .setExpiration(new Date(System.currentTimeMillis() + 3600000))
    //                .setExpiration(new Date(System.currentTimeMillis())) // 立刻超时
                    // nbf 明天才生效
                    // .setNotBefore(new DateTime().plusDays(1).toDate())
                    .setIssuedAt(new Date())
                    .setIssuer("junit")
                    // 签名设置
                    .signWith(SignatureAlgorithm.HS256, secret)
                    .compact();
    
            System.out.println("加密后access_token为:" + token);
    
    
            // token分为三部分,header.payload.signatrue , 前2个部分可以直接用 base64 反向解析得出结果
            String[] split = token.split("\\.");
            String header = new String(Base64.getDecoder().decode(split[0].getBytes()));
            System.out.println("header:" + header);
            String payload = new String(Base64.getDecoder().decode(split[1].getBytes()));
            System.out.println("payLoad:" + payload);
    
            // token检验
            Claims body = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    
            System.out.println("------------JWT解析结果--------------");
            body.forEach((k, v) -> {
                System.out.println("K:" + k + "\t v:" + v);
            });
        }
    }
    
    

    运行结果:

    加密后access_token为:eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiIwMDciLCJzdWIiOiJzaHVzbSIsImV4cCI6MTU1NDYyNjQ4MCwiaWF0IjoxNTU0NjIyODgwLCJpc3MiOiJqdW5pdCJ9.Ggfjx0dqUIjLLXHMs-s2Y_yLKcJCeAcwbmyTyx3h6T8
    header:{"alg":"HS256"}
    payLoad:{"userId":"007","sub":"shusm","exp":1554626480,"iat":1554622880,"iss":"junit"}
    ------------JWT解析结果--------------
    K:userId     v:007
    K:sub    v:shusm
    K:exp    v:1554626480
    K:iat    v:1554622880
    K:iss    v:junit
    

    相关文章

      网友评论

          本文标题:JWT令牌速成

          本文链接:https://www.haomeiwen.com/subject/cossiqtx.html