网上关于 JWT的介绍已经很多了,我们学习的时候可以参考下官网 https://jwt.io/introduction/
JWT组成
- Header(头部)
- Payload(负载)
- Signature(签名)
生成的token串为: xxxxx.yyyyy.zzzzz (Header.Payload.Signature)
Header
- alg (algorithm):签名的算法
- typ (type):JWT 令牌统一写为JWT
{
"alg": "HS256",
"typ": "JWT"
}
Payload
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
除了上述的7个字段,我们可以添加自己的字段
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Signature
部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
JwtUtils
public class JwtUtils {
/**
* 生成JWT字符串
* @return JWT
*/
public static String generateJWT(){
//设置启动时间和过期时间
long nowMillis = System.currentTimeMillis();
long expMillis = nowMillis + 300000;
Date now = new Date(nowMillis);
Date expDate = new Date(expMillis);
//JWT中存的信息
Map<String,Object> map=new HashMap<>();
map.put("username","marion");
map.put("uid","123456789");
JwtBuilder builder = Jwts.builder();
builder.setId("1")
.setSubject("jwt")
.setIssuer("123456")
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256,getKey())
.setExpiration(expDate)
.addClaims(map);
//获取koken
return builder.compact();
}
/**
* 解析JWT字符串获取Claims容器
* @param jwt JWT字符串
* @return Claims容器
* @throws Exception 解析异常
*/
public static Claims parseJWT(String jwt) throws Exception {
SecretKey secretKey = getParseKey();
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(jwt)
.getBody();
}
/**
* 获取解析用密钥
* @return 解析用密钥对象
*/
public static SecretKey getParseKey(){
byte[] encodedKey = "123456".getBytes();
return new SecretKeySpec(encodedKey, 0, encodedKey.length, "");
}
/**
* 获取加密用密钥
* @return 加密用密钥对象
*/
public static SecretKey getKey(){
byte[] encodedKey = "123456".getBytes();
return new SecretKeySpec(encodedKey, 0, encodedKey.length, "");
}
}
单元测试
@Test
public void jwtTest() throws Exception {
String jwt = JwtUtils.generateJWT();
System.out.println(jwt);
System.out.println("-----");
Claims claims = JwtUtils.parseJWT(jwt);
System.out.println(claims.getSubject());
System.out.println(claims.get("username")+"\t"+claims.get("uid"));
}
控制台输出
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoiand0IiwiaXNzIjoiMTIzNDU2IiwiaWF0IjoxNjEzOTg2MTA3LCJleHAiOjE2MTM5ODY0MDcsInVpZCI6IjEyMzQ1Njc4OSIsInVzZXJuYW1lIjoibWFyaW9uIn0.aFijm2CqZsQWcL-Q2ydURNwxsPa_QKVs2vPCMFjnvIs
-----
jwt
marion 123456789