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. 结语
该文章主要是记录在工作中的学习知识,第一篇博客;不足之处望见谅!!!
本文介绍了JWT(JSON Web Token)的基本概念,包括其主要结构(header、payload、signature)及其具体实现方式。详细阐述了JWT各组成部分的作用及编码过程,并提供了Header与Payload类的实现代码。
2万+





