1 什么是JWT
JWT是基于json制作的一个web token的一套规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息,它属于一种无状态的数据,它主要有两大使用场景:认证和数据传递。
2 JWT 的内容
JWT的内容如下:
eyJhbGciOiJIUzUxMiJ9.eyJwYXNzd29yZCI6IjQ1NiIsImV4cCI6MTY2MDUyOTI0MCwiaWF0IjoxNjYwNTI3NDQwLCJ1c2VybmFtZSI6InpoYW5nc2FuIn0.LbtbH4DRn7W8PAzre1Cflpfg3W9grzPQIs7Z_86q5J9Gm8YiRxvBjZ7gPmils6LBzvmFKmvcgywwHELLPlCQKQ
由上面的JWT的内容我们根据“.”这个字符把内容隔开看,内容一共分为三段,如下
eyJhbGciOiJIUzUxMiJ9
eyJwYXNzd29yZCI6IjQ1NiIsImV4cCI6MTY2MDUyOTI0MCwiaWF0IjoxNjYwNTI3NDQwLCJ1c2VybmFtZSI6InpoYW5nc2FuIn0
LbtbH4DRn7W8PAzre1Cflpfg3W9grzPQIs7Z_86q5J9Gm8YiRxvBjZ7gPmils6LBzvmFKmvcgywwHELLPlCQKQ
这三段内容也就是jwt的主要组成部分,看到这三段内容,我们肯定会不由自主的想到,这三段内容到底是什么呢?有什么作用呢?安全起见为什么一定是三段呢?
2.1 第一段名为Header
header里面存放的是一个内容包含了算法名称已经类型的json对象,然后以base64处理之后的数据。
2.2 第二段名为Payload
payLoad 里面存放的是user的数据的json对象,然后以base64处理之后的数据。
2.3 第三段名为 Signature
signature 里面存放的是前面两个的数据组合起来,然后加上一个加密盐通过第一段设置的加密方式加密起来,然后以base64处理的数据。
3 JWT的demo
在 pom.xml导入依赖 如下
JWT的生成token以及token的解析代码如下:
package com.zw.jwtdemo.util;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
public class JwtUtil {
private String keyScret ="123456";
private int expiryTime = 30;
public String getToken(Map<String, Object> claims) {
if(claims == null || claims.size() == 0) {
return null;
}
Date createTime = new Date();
Calendar calander = Calendar.getInstance();
calander.setTime(createTime);
calander.add(Calendar.MINUTE, expiryTime);
return Jwts.builder()
//payload
//设置携带的内容即数据信息。
.setClaims(claims)
//设置过期时间
.setExpiration(calander.getTime())
//设置创建时间
.setIssuedAt(createTime)
//设置加密盐和签名算法
.signWith(SignatureAlgorithm.HS512, keyScret)
//数据压缩得到一个字符串
.compact();
}
public Map<String,Object> parseToken(String token) {
Claims claims = Jwts.parser()
//设置加密盐
.setSigningKey(keyScret)
//通过压缩的jwt
//字符串解析出数据信息
.parseClaimsJws(token)
//返回数据信息;
//返回的内容是一个hashMap
.getBody();
return claims;
}
public static void main(String[] args) {
Map<String, Object> map = new HashMap<String,Object>(); JwtUtil jwtUtil = new
JwtUtil(); map.put("username", "zhangsan"); map.put("password", "456");
String token =jwtUtil.getToken(map); System.out.println(token);
Map<String,Object> map2 = jwtUtil.parseToken(token); Set<String> keys =
map2.keySet(); for(String key: keys) { System.out.println(key + "=" +
String.valueOf(map2.get(key))); }
}
}
//输出结果
eyJhbGciOiJIUzUxMiJ9.eyJwYXNzd29yZCI6IjQ1NiIsImV4cCI6MTY2MTE1MjkyOCwiaWF0IjoxNjYxMTUxMTI4LCJ1c2VybmFtZSI6InpoYW5nc2FuIn0.BC-M5R9kThhW1H7DF0c5OLczQyV6xSOc6Sj3kS2bU67dpjGUmCcMOyFF9H2x0mK7z6J4zqzsB0Z0uJ48CGtDqw
password=456
exp=1661152928
iat=1661151128
username=zhangsan
上面的代码段便是JWT的代码段了,代码比较简单生成的JWT也是通过“.”隔开的三段字符串拼接而成。接下来我没还是带着我之前提出的三个问题,分析下源码。
4 JWT的源码分析
4.1 JWT加密的源码
JWT加密的源码主要就是compact方法,我们进入到compact方法看看,这个方法里面到底有啥内容。
@Override
public String comp