jwt三种方式

package library.book.demo.config.loginconfig;

import com.alibaba.fastjson.JSON;
import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultHeader;
import io.jsonwebtoken.impl.DefaultJwtBuilder;
import io.jsonwebtoken.impl.crypto.DefaultJwtSigner;
import io.jsonwebtoken.impl.crypto.JwtSigner;
import io.jsonwebtoken.impl.lang.LegacyServices;
import io.jsonwebtoken.io.Encoder;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.io.Serializer;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.io.IOException;
import java.security.KeyPair;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt登录
 */
public class JwTLogin {

    public static void main(String[] args) throws IOException {

        //0  原始签名
        String header0 = "{\"alg\":\"HS256\"}";
        String claims0 = "{\"sub\":\"wangbiao\",\"aud\":\"wangbiao\"}";

        Encoder<byte[], String> base64UrlEncoder = Encoders.BASE64URL;
        String hed =base64UrlEncoder.encode(header0.getBytes("UTF-8"));

        Map map= (Map) JSON.parse(claims0);
        Serializer<Map<String,?>> serializer= LegacyServices.loadFirst(Serializer.class);
        byte[] clambyte0= serializer.serialize(map);


        /**
         * payload为空String方法转化字节数组,不然转化JSON序列化,默认payload为null 即上面的序列化
         * byte [] claimbyte=claims0.getBytes("UTF-8");
         */


        /**
         *  默认jwt不需要压缩
         *        DeflateCompressionCodeWb deflateCompressionCodecss=new DeflateCompressionCodeWb();
         *        claims压缩字节
         *        byte[]  clambyte1 =deflateCompressionCodecss.doCompress(clambyte0);
         */
        //key的另一种创建方式
        //Key key = new SecretKeySpec("5aSn55Ge6ZO25LiA57uf5rGf5rmWLOWNg+eni+S4h+S7ow==".getBytes(),
        //            SignatureAlgorithm.HS512.getJcaName());


        //签名key
        SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
        //        字节在编码
        String cla= base64UrlEncoder.encode(clambyte0);
        String concatenated= hed+'.'+cla;

        //签名方式
        SignatureAlgorithm algorithm=SignatureAlgorithm.HS256;
        JwtSigner defaultJwtBuilder=new DefaultJwtSigner(algorithm,key,base64UrlEncoder);
        String base64UrlSignature = defaultJwtBuilder.sign(concatenated);
        String sss= concatenated+'.'+base64UrlSignature;
        System.out.println(sss);
        //验签
        System.out.println(Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(sss));





//        1 设置token方式一
//         最简单token  使用默认的属性
        KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256);
        Date date=new Date();
       long sd= date.getTime()+60000;
        Date date1=new Date(sd);
        String jws = Jwts.builder() // (1)
                //header设置方式1  设置参数
                .setHeaderParam("ad", "ad")//
                .setHeaderParam("ss", "ss")
                .setSubject("Joe")      // (2)
                .setIssuedAt(date)
                .setExpiration(date1)
                //私匙签名
                .signWith(keyPair.getPrivate())          // (3)私钥加密
                .compact();
        System.out.println(jws);
        System.out.println(Jwts.parserBuilder().setSigningKey(keyPair.getPublic()).build().parseClaimsJws(jws).getBody().getSubject().equals("Joe"));
         //公匙验签
        System.out.println(Jwts.parserBuilder().setSigningKey(keyPair.getPublic()).build().parseClaimsJws(jws));






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

        //2设置token方式二 设置头
        Header header = new DefaultHeader();
        header.put("alg", "HS256");
//       //header设置方式1  设置map
        Map<String, Object> claims = new HashMap<>();
        claims.put("aud", "wangbiao");
        claims.put("sub", "wangbiao");
        String jwss = Jwts.builder()
                .setHeader((Map<String, Object>) header)
                .setClaims(claims)
                .setExpiration(new Date(System.currentTimeMillis() + 5000))
                .signWith(key)////签名key
                .compact();
        System.out.println(jwss);
        //验签
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        System.out.println(Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jwss));





        //3设置token方式二 设置头 自定义字符串
        //签名方式  自定义key字符串
        SignatureAlgorithm algorithm0=SignatureAlgorithm.HS256;
        String ss1="fdsfsfsdfsfsfdsfsfwewprfeppppppp";//原始签名注意保存不可外部泄露
        String ssss0 =base64UrlEncoder.encode(ss1.getBytes("UTF-8"));
        Header header1 = new DefaultHeader();
        header1.put("alg", "HS256");//HS256必须大于等于32字符(大于等于2048位才行)
        //header设置方式1  设置map
        Map<String, Object> claims1 = new HashMap<>();
        claims1.put("aud", "wangbiao");//用于加密的信息
        claims1.put("sub", "wangbiao");//用于加密的信息
        String jwss0 = Jwts.builder()
                .setHeader((Map<String, Object>) header1)
                .setClaims(claims1)
                .signWith(algorithm0,ssss0)
                .compact();
        System.out.println(jwss0);//加密的token一般生成后客户端每次请求都会带到服务端
        //验签
        System.out.println(Jwts.parserBuilder().setSigningKey(ssss0).build().parseClaimsJws(jwss0));
    }
}

 

签名:key
token:token
用签名去解密
得到一个集合
获取用户自定义信息与注册时用户信息比较是否一致
 Jws<Claims> claimsJws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);

 

posted @ 2021-04-20 22:02  余生请多指教ANT  阅读(171)  评论(0编辑  收藏  举报