• JWT


    JWT

      Json Web Token(JWT) 是个轻量级规范,允许用户和服务器之间传递安全可靠信息;

    JWT构成

      JWT 实际是个字符串,由 header(头部), payload(载荷), signature(签名)组成;

    header(头部)

      头部描述 JWT 最基本信息,例如类型和签名用的算法,比如

    {"typ":"JWT","alg":"HS256"}

           以上头部 签名是HS256算法, base64加密

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

    payload(载荷) 

      (1)标准中注册的声明(建议但不强制使用)

    iss: jwt签发者
    sub: jwt所面向的用户
    aud: 接收jwt的一方
    exp: jwt的过期时间,这个过期时间必须要大于签发时间
    nbf: 定义在什么时间之前,该jwt都是不可用的.
    iat: jwt的签发时间
    jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

      (2)公共声明

      公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密. 

      (3)私有声明

     私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
    这个指的就是自定义的claim。比如下面面结构举例中的admin和name都属于自定的claim。这些claim跟JWT标准规定的claim区别在于:
    JWT规定的claim,JWT的接收方在拿到JWT之后,都知道怎么对这些标准的claim进行验证(还不知道是否能够验证);
    而private claims不会验证,除非明确告诉接收方要对这些claim进行验证以及规则才行。

          定义一个 payload

    {"sub":"1234567890","name":"John Doe","admin":true}

          对其 base64 加密得到 jwt 第二部分

    eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

      

    签证(signature)

      jwt 第三部分是一个签证信息,用于校验数据是否被篡改;

           由header(base64后的), payload(base64之后的), secret(盐) 三部分组成:

      这个部分需要base64加密后的header和base64加密后的payload使用 . 连接组成的字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,然后构成 jwt 第三部分。

    TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

      将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

      注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

      签名总结:Base64(头) + Base64(载荷) + 密钥(盐)  ---》加密 采用 头中指定的算法

      签名作用: 用于校验令牌 是否篡改

            令牌:

     

    加密测试

        @Test
        public void testCreateToken(){
            JwtBuilder builder = Jwts.builder();
            builder.setIssuer("测试人");
            builder.setIssuedAt(new Date());
            builder.setSubject("令牌Test");
            builder.signWith(SignatureAlgorithm.HS256,"itCheck");
            System.out.println(builder.compact());
        }
    

    输出

    eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiLmtYvor5XkuroiLCJpYXQiOjE1OTc3MzM4MjUsInN1YiI6IuS7pOeJjFRlc3QifQ.Mjq7bFrsJELQBr0j5wYm4LoY3QiNerUMVJ5wDQKN590

    解密测试

        @Test
        public void testCreateToken(){
            JwtBuilder builder = Jwts.builder();
    
            //构建令牌对象
            builder.setIssuer("测试人");
            builder.setIssuedAt(new Date());
            builder.setSubject("令牌Test");
    
    
            //添加载荷
            Map<String, Object> userInfo = new HashMap<String,Object>();
            userInfo.put("company","Baidu");
            userInfo.put("address","Shenzhen");
            builder.addClaims(userInfo); //添加载荷
    
            builder.signWith(SignatureAlgorithm.HS256,"itCheck");
            System.out.println(builder.compact());
        }
    

      

    输出 

    {iss=测试人, iat=1597733825, sub=令牌Test}
  • 相关阅读:
    C#中的转义字符verbatim string
    how to use Inspector in fiddler
    how to use composer in fiddler
    CodeWars上的JavaScript技巧积累
    What's the difference between using “let” and “var” to declare a variable in JavaScript?
    Loop through an array in JavaScript
    Why does typeof array with objects return “Object” and not “Array”?
    Owin and Startup class
    Qt Widgets、QML、Qt Quick的区别
    飞舞的蝴蝶(GraphicsView框架)
  • 原文地址:https://www.cnblogs.com/Jomini/p/13523124.html
Copyright © 2020-2023  润新知