jwt 全称为 json web token,由 Header 头部、Payload 负载(payload一般用于存数据,注:获取里面数据并不需要解密)和 Signature 签名组成,jwt其实内部就是一个token进行特殊处理,token用于登录身份认证,而它相比session的好处更明显。
session:存在服务器,占用服务器资源,对服务器不友好,负载均衡下,session不共享会导致session丢失。
token:只保存在客户端,浏览器每次发送请求,都会将token携带过去,但是服务器需要查库验证。
jwt:只保存在客户端,服务器直接通过secret解密验证,不需要查库(这就导致secret不能丢失)。
注:session在负载均衡下不共享,可以通过 SpringSession 解决,使用session最主要的是占用服务器资源。
jwt组成如下:
Header:
type:token类型
alg:使用算法
Payload:
存放一些信息
signature:
用于指定算法,将编码后的header、payload和一个secret进行加密
注:最终生成的token字符串为 编码加密header.编码加密payload.编码加密secret
接下来看看Java代码如何实现jwt创建、获取数据、认证的流程。
导入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
创建jwt
// 生成token
public static String creatJwt(){
// 设置头部信息,一般这样设置不用改
Map<String,Object> map=new HashMap<String,Object>();
map.put("alg","HS256");
map.put("typ","JWT");
// 设置载体信息
String val="存放数据";
// 过时时间
Calendar nowTime=Calendar.getInstance();
nowTime.add(Calendar.MINUTE,5);
Date expiresTime = nowTime.getTime();
// 定义常量,用于特殊算法计算拼接尾部,用于公共秘钥加密
String secret="11111";
String jwt=JWT.create()
.withHeader(map) //第一部分内容
.withClaim("text",val) //存放信息
.withIssuedAt(new Date()) //签发时间
.withExpiresAt(expiresTime) //结束时间
.sign(Algorithm.HMAC256(secret)); //用公共秘钥加密
return jwt;
}
获取数据
// 获取token内容数据
public static String getTokenText(String token) {
try {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("text").asString();
} catch (JWTDecodeException e) {
return null;
}
}
注:获取token的数据,并不需要进行解密。
认证token
// token校检器,参数token为生成的jwt,参数secret为秘钥
public static boolean ifTrue(String token,String secret){
try{
// 创建校检器
Algorithm algorithm=Algorithm.HMAC256(secret);
JWTVerifier jwtVerifier =JWT.require(algorithm).build();
// 进行校检
DecodedJWT jwt=jwtVerifier.verify(token);
return true;
}catch (Exception exception){
return false;
}
}
以下是我使用测试时使用的控制器,供参考方便使用
@RestController
public class jwtController {
// 创建token
@GetMapping(value = "/setJwt")
public String setJwt(HttpServletResponse response){
String jwtUtil=JwtUtil.creatJwt();
// 把token放在请求头
response.setHeader("token",jwtUtil);
System.out.println("创建一个token内容如下:"+jwtUtil);
return jwtUtil;
}
// 获取数据
@GetMapping(value = "/getJwt")
public String getJwt(HttpServletRequest request){
// 获取请求头某个内容
String token=request.getHeader("token");
System.out.println("获取的token为"+token);
String jwtUtil=JwtUtil.getTokenText(token);
return jwtUtil;
}
// 校检token
@GetMapping(value = "/ifJwt")
public boolean ifJwt(){
boolean ifjwt=JwtUtil.ifTrue("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXh0Ijoi5a2Y5pS-5pWw5o2uIiwiZXhwIjoxNjUwNjIxMjAwLCJpYXQiOjE2NTA2MjA5MDB9.LeKu8jfCH9bzOLzK4lHYkyWZhOQv4BS_kjwrO4O2wpE","11111");
return ifjwt;
}
}
通过上面的内容就能完成简单的jwt操作了,jwt在验证方面很常用,结合缓存、过滤器能够让我们更方便地进行验证。
源码地址:https://github.com/Yuqn/jwt_cre_sel_get.git
以上就是 jwt 的一些用法,可能存在不足或错误,如有发现请指出来。