对呀JWT我们对它的使用就是将它作为登录的标识符,以及通过解析改JWT我们可以获取到我们需要的一些信息,下面我们来操作一下,看看怎样生成JWT,以及解析JWT
JWT的组成:header,payload,signature
payload就是保存我们的用户信息的地方,所以我们到时候解析的时候,只需要解析payload这一块就可以了
现在我们先来创建一个JwtPayLoad的实体类
JwtPayLoad实体类的作用,你们等一会就知道了
@Data
public class JwtPayLoad {
/**
* id
*/
private String id;
/**
* account
*/
private String account;
/**
* password
*/
private String password;
public JwtPayLoad(String id, String account, String password) {
this.id = id;
this.account = account;
this.password = password;
}
public JwtPayLoad() {
}
}
因为jwt其实就是一个工具类,所以我们把所有的操作就创建到JwtUntils工具类中
在这里插入图片描述
我们一开始给我们的header加两个算法,给他进行头部加密
/**
* jwt 头信息加密
*
* @return
*/
private static Map getHeader() {
Map<String, Object> headerClaims = new HashMap<>(2);
headerClaims.put(PublicClaims.ALGORITHM, HEADER_ALG);
headerClaims.put(PublicClaims.TYPE, HEADER_TYPE);
return headerClaims;
}
下面我们进行JWT(下面我都叫它token)的生成
/**
* 生成token
* @param jwtPayLoad
* @return
*/
public static String generate(JwtPayLoad jwtPayLoad){
JWTCreator.Builder builder = JWT.create();
builder.withHeader(getHeader())//头信息
.withIssuedAt(new Date())//创建时间
//过期时间(可以根据项目要求设置)
.withExpiresAt(new Date(System.currentTimeMillis()+100000))
//.withIssuer()//颁发者唯一标识,这里不写
.withJWTId(jwtPayLoad.getId());
try {
//将JwtPayLoad中的字段加入builder
//builderClaim是一个我们自己封装的方法,下面有
builder = builderClaim(jwtPayLoad, builder);//token第二部分
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//返回token sign签名(token第三部分)
return builder.sign(Algorithm.HMAC256("123456")) ;
}
builderClaim方法
public static JWTCreator.Builder builderClaim(JwtPayLoad payLoad,JWTCreator.Builder builder) throws IllegalAccessException {
//通过实体类对象,通过反射获取该实体类的所有字段
Field[] fields = payLoad.getClass().getDeclaredFields();
//将字段逐个加入builder
for (Field field : fields) {
//字段名
String name = field.getName();
// f.setAccessible(true)的作用就是让我们在用反射时访问私有变量的权限
field.setAccessible(true);
//获取字段的值
Object value = field.get(payLoad);
//String类型是以为我这边设置的值都是String类型的,如果不一样的话,可以自己封装这个withClaim方法
builder.withClaim(name, (String) value);
}
return builder;
}
这种就是封装的一种方式
所以JwtPayLoad的作用就相当于是我们登陆的信息的实体类,然后将这个实体类封装进入token
我们测试一下
@Test
void contextLoads() {
JwtPayLoad jwtPayLoad=new JwtPayLoad();
jwtPayLoad.setId("1");
jwtPayLoad.setAccount("123456");
jwtPayLoad.setPassword("123456");
String token = JwtUntils.generate(jwtPayLoad);
System.out.println(token);
}
以上就是token生成成功了
下面就是我们token的解析了
其实解析token超级简单,因为token它的payload就是通过Base64编码加密的,所以我们获取到token的payload部分后直接将它解析了就好
/**
* 根据token解析出数据
* @param token
* @return
*/
public static String getPayloadStringByToken(String token) throws Exception {
try {
//将token以"."分割
String[] split = token.split("\\.");
//并获取索引为1的部分,命名为payLoad
String payLoad=split[1];
//通过Base64字符串方式解析
byte[] bytes = Base64.decodeBase64(payLoad);
return new String(bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new Exception("解析失败,重新登录");
}
}
这个解析出来的结果就是一个json字符串
所以我们后面想要获取什么,我们都可以直接通过这个方法获取就好
给你们举一个例子
/**
* 解析token获取id
* @param token
* @return
* @throws Exception
*/
public static String getPayLoadId(String token) throws Exception {
//获取payLoad信息
String payload = getPayloadStringByToken(token);
//将payLoad序列化
JwtPayLoad jwtPayLoad = JsonIterator.deserialize(payload, JwtPayLoad.class);
return jwtPayLoad.getId();
}
要是用JsonIterator.deserialize这个方法需要导入下面这个依赖
<!--json序列化-->
<dependency>
<groupId>com.jsoniter</groupId>
<artifactId>jsoniter</artifactId>
<version>0.9.8</version>
</dependency>
好了,JWT的获取以及解析就是这样的了,可能有些我描述的有点问题,因为我都是通过我自己的理解来写的,希望可以帮助到你们