JWT

本文介绍了JWT(JSON Web Token)的基本概念,包括其主要结构(header、payload、signature)及其具体实现方式。详细阐述了JWT各组成部分的作用及编码过程,并提供了Header与Payload类的实现代码。

JWT的具体实现

1. JWT主要结构

形式:heder.payload.signature
三部分通过圆点(.)连接,形如:xxxxx.yyyyy.zzzzz

  • header

    由 token类型(type) + 算法名称组成
    需要将该header部分进行编码(Base64Url)

  • payload

    负载 主要是存放一些有效信息,比如jwt签发者、签发时间、过期时间、还可以添加用户的信息(用户名、用户)等。
    需要将该payload部分进行编码(Base64Url)

    负载部分建议(不强制)包含以下几个部分面 
    	iss: jwt签发者
    	sub: jwt所面向的用户
    	aud: 接收jwt的一方
    	exp: jwt的过期时间,这个过期时间必须要大于签发时间
    	nbf: 定义在什么时间之前,该jwt都是不可用的.
    	iat: jwt的签发时间
    	jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击
    	可以添加任何信息,但一般添加的是与用户相关的非私密的信息(用户名、用户id等)
    
  • signature

    由 header + payload + secret 通过header中声明的算法生成
    生成signature方式:HS256(Base64Url(header) + “.” + Base64Url(payload), signature)
    这里的签名算法是在header中所声明的算法

2. JWT的具体实现

2.1 创建Header类

 @Data
 public class Header {
     /**
      * 确定加密算法
      */
     private String alg;
     /**
      * 令牌类型
      */
     private String typ;
 
     public Header() {
     	//一般jwt使用的算法为 HMAC SHA256
         alg = "HS256";
         //令牌(token)类型为 JWT
         typ = "JWT";
     }
 
     public Header(String alg, String typ) {
         this.alg = alg;
         this.typ = typ;
     }
     /**
      * @return String
      */
     public String toJson() {
         return JSON.toJSONString(this);
     }
 
     /**
      *	JWT的header是需要进行编码(Base64Url)的
      * @return String
      */
     public String toJSONBase64URL() {
         return Base64.getUrlEncoder()
                 .withoutPadding()
                 .encodeToString(this.toJson().getBytes(StandardCharsets.UTF_8));
     }
}

2.2 创建Payload类

@Data
@NoArgsConstructor
public class Payload {
    /**
     * 签发者
     */
    private String iss;
    /**
     * 过期时间戳,该时间应该大于创建时间
     */
    private Long exp;
    /**
     * 当前创建时间,即JWT签发时间
     */
    private Long iat;
    /**
     * userId
     */
    private Long id;
    /**
     * 用户名
     */
    private String name;
  
    public Payload(String iss, Long exp, Long iat, Long id, String name){
        this.iss = iss;
        this.exp = exp;
        this.iat = iat;
        this.id = id;
    }

    /**
     * @return String
     */
    public String toJson() {
        return JSON.toJSONString(this);
    }

    /**
     * 同理,对payload部分进行编码
     * @return String
     */
    public String toJsonBase64Url() {
        return Base64.getUrlEncoder()
                .withoutPadding()
                .encodeToString(this.toJson().getBytes(StandardCharsets.UTF_8));
    }
}

2.3 创建JWT工具类

public final class JwtUtils {

    /**
     * 3
     */
    private static final int THREE = 3;
    /**
     * 2
     */
    private static final int TWO = 2;

    private JwtUtils() {
    }

    /**
     * 生成jwt
     *
     * @param header  令牌头部
     * @param payload 负载
     * @param secret  密钥
     * @return String
     */
    public static String encoder(Header header, Payload payload, String secret) {
    	//将header、payload进行Base64Url编码
        String headerJsonBase64Url = header.toJSONBase64URL();
        String payloadJsonBase64Url = payload.toJsonBase64Url();
        //生成signature,SHA256是加密工具类
        String signature = SHA256.hmacSha256(headerJsonBase64Url + "." + payloadJsonBase64Url, secret);
        return headerJsonBase64Url + "." + payloadJsonBase64Url + "." + signature;
    }

    /**
     * 解析jwt
     *
     * @param jwtString jwt内容
     * @param secret    密钥
     * @return Payload
     */
    public static Payload decoder(String jwtString, String secret) {
        String[] jwtStrings = jwtString.split("\\.");
        if (jwtStrings.length != THREE) {
            return null;
        }
        //验证是否有效
        String signature = SHA256.hmacSha256(jwtStrings[0] + "." + jwtStrings[1], secret);
        if (!signature.equals(jwtStrings[TWO])) {
            return null;
        }

        //解析成Payload
        String payloadJson = new String(Base64.getUrlDecoder().decode(jwtStrings[1].getBytes(StandardCharsets.UTF_8)));
        Payload payload = JSON.parseObject(payloadJson, Payload.class);

        return payload;
    }
}

2.4 创建加密工具类

该部分用到时,再去查找相应资料

3. 结语

该文章主要是记录在工作中的学习知识,第一篇博客;不足之处望见谅!!!

4. 参考资料

参考资料来源

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值