目录
  • 1. 什么是jwt
  • 2. jwt的构成
    • 2.1 头部(header)
    • 3. jjwt的介绍
      • 4. jjwt的使用
        • 5. jwt工具类

          1. 什么是jwt

          json web token(jwt)是一个轻量级的认证规范,这个规范允许我们使用jwt在用户和服务器之间传递安全可靠的信息。其本质是一个token,是一种紧凑的url安全方法,用于在网络通信的双方之间传递。

          2. jwt的构成

          一个jwt实际上就是一个字符串,它由三部分组成:头部、载荷与签名

          2.1 头部(header)

          头部用于描述关于该jwt的最基本的信息,例如其类型以及签名所用的算法等

          头部可以被表示成一个json对象

          {"typ":"jwt","alg":"hs256"}
          

          在头部指明了签名算法是hs256算法。 我们进行base64编码,编码后的字符串如下:

          eyj0exaioijkv1qilcjhbgcioijiuzi1nij9
          

          base64是一种基于64个可打印字符来表示二进制数据的表示方法。

          由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。

          三个字节有24个比特,对应于4个base64单元,即3个字节需要用4个可打印字符来表示。

          jdk 中提供了非常方便的 base64encoder 和 base64decoder,用它们可以非常方便的完成基于 base64 的编码和解码

          2.2 载荷(playload)

          载荷是存放有效信息的地方,这些有效信息包含三个部分:

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

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

          2.2.2 公共的声明

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

          2.2.3 私有的声明

          私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息

          比如下面举例中的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
          

          2.3 签证(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就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了

          3. jjwt的介绍

          jjwt是一个提供端到端的jwt创建和验证的java库

          官方文档:

          4. jjwt的使用

          <!--鉴权-->
          <dependency>
              <groupid>io.jsonwebtoken</groupid>
              <artifactid>jjwt</artifactid>
              <version>0.9.0</version>
          </dependency>
          
          import com.sun.scenario.effect.impl.sw.sse.sseblend_src_outpeer;
          import io.jsonwebtoken.claims;
          import io.jsonwebtoken.jwtbuilder;
          import io.jsonwebtoken.jwts;
          import io.jsonwebtoken.signaturealgorithm;
          import java.util.date;
          import java.util.hashmap;
          public class testjwt {
              public static void main(string[] args) {
                  testcreatejwt();
                  testparsejwt();
              }
              public static void testcreatejwt() {
                  jwtbuilder builder = jwts.builder()
                          .setid("404")                   // 设置唯一编号
                          .setsubject("邢立豹")            // 设置主题 可以是json数据
                          .setissuedat(new date())        // 设置签发日期
                          // .setexpiration(new date())      // 设置过期时间
                          // 设置签名 使用hs256算法 并设置secretkey(字符串)
                          .signwith(signaturealgorithm.hs256, "lichun");
                  hashmap<string, object> userinfo = new hashmap<>();
                  userinfo.put("name","枯木何日可逢春");
                  userinfo.put("age", "21");
                  builder.addclaims(userinfo);
                  system.out.println(builder.compact());
              }
              public static void testparsejwt() {
                  string str = "eyjhbgcioijiuzi1nij9.eyjqdgkioii0mdqilcjzdwiioilpgqlnq4vosbkilcjpyxqioje2mza2odazntmsimv4cci6mtyzmdy4mdm1mywibmftzsi6iuaer-acqos9leaxpewpr-maouaypsisimfnzsi6ijixin0.59i5xflz9a-wtoji9kxkf7zqp4zslewrc5dylcy_akc";
                  claims claims = jwts.parser()
                          .setsigningkey("lichun")
                          .parseclaimsjws(str)
                          .getbody();
                  system.out.println(claims);
              }
          }
          

          5. jwt工具类

          package com.lichun.utils;
          import io.jsonwebtoken.claims;
          import io.jsonwebtoken.jwtbuilder;
          import io.jsonwebtoken.jwts;
          import io.jsonwebtoken.signaturealgorithm;
          import javax.crypto.secretkey;
          import javax.crypto.spec.secretkeyspec;
          import java.util.base64;
          import java.util.date;
          public class jwtutil {
              // 有效期
              public static final long jwt_ttl = 3600000l;
              // jwt令牌信息
              public static final string jwt_key = "lichun";
              public static string createjwt(string id, string subject, long ttlmillis) {
                  signaturealgorithm signaturealgorithm = signaturealgorithm.hs256;
                  long nowmillis = system.currenttimemillis();
                  date now = new date(nowmillis);
                  if (ttlmillis == null) {
                      ttlmillis = jwt_ttl;
                  }
                  long expmillis = nowmillis + ttlmillis;
                  date expdate = new date(expmillis);
                  secretkey secretkey = generalkey();
                  jwtbuilder builder = jwts.builder()
                          .setid(id)                      // 设置唯一编号
                          .setsubject(subject)            // 设置主题 可以是json数据
                          .setissuer("admin")
                          .setissuedat(now)               // 设置签发日期
                          .setexpiration(expdate)         // 设置过期时间
                          // 设置签名 使用hs256算法 并设置secretkey(字符串)
                          .signwith(signaturealgorithm.hs256, secretkey);
                  return builder.compact();
              }
              /**
               * 生成加密secretkey
               * @return
               */
              public static secretkey generalkey() {
                  byte[] encodedkey = base64.getencoder().encode(jwt_key.getbytes());
                  secretkey key = new secretkeyspec(encodedkey, 0, encodedkey.length, "aes");
                  return key;
              }
              /**
               * 解析令牌数据
               */
              public static claims parsejwt(string jwt) throws exception {
                  secretkey secretkey = generalkey();
                  return jwts.parser()
                          .setsigningkey(secretkey)
                          .parseclaimsjws(jwt)
                          .getbody();
              }
          }
          
          

          以上就是如何使用jjwt及jwt讲解和工具类的详细内容,更多关于jwt讲解与jjwt使用的资料请关注www.887551.com其它相关文章!