概述

由来

从5.7.0开始,Hutool提供了零依赖的JWT(JSON Web Token)实现。

JWT介绍

相关资料网络上非常多,可以自行搜索,简单点说JWT就是一种网络身份认证和信息交换格式。

结构

  • Header 头部信息,主要声明了JWT的签名算法等信息
  • Payload 载荷信息,主要承载了各种声明并传递明文数据
  • Signature 签名,拥有该部分的JWT被称为JWS,也就是签了名的JWS,用于校验数据

整体结构是:

header.payload.signature

使用

JWT模块的核心主要是两个类:

  1. JWT类用于链式生成、解析或验证JWT信息。
  2. JWTUtil类主要是JWT的一些工具封装,提供更加简洁的JWT生成、解析和验证工作

JWT生成

  1. HS265(HmacSHA256)算法
// 密钥
byte[] key = "1234567890".getBytes();

String token = JWT.create()
	.setPayload("sub", "1234567890")
	.setPayload("name", "looly")
	.setPayload("admin", true)
	.setKey(key)
	.sign();

生成的内容为:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9.536690902d931d857d2f47d337ec81048ee09a8e71866bcc8404edbbcbf4cc40
  1. 其他算法
// 密钥
byte[] key = "1234567890".getBytes();

// SHA256withRSA
String id = "rs256";
JWTSigner signer = JWTSignerUtil.createSigner(id, 
	// 随机生成密钥对,此处用户可自行读取`KeyPair`、公钥或私钥生成`JWTSigner`
	KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));

String token = JWT.create()
	.setPayload("sub", "1234567890")
	.setPayload("name", "looly")
	.setPayload("admin", true)
	.setSigner(signer)
	.sign();
  1. 不签名JWT
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9.
String token = JWT.create()
	.setPayload("sub", "1234567890")
	.setPayload("name", "looly")
	.setPayload("admin", true)
	.setSigner(JWTSignerUtil.none())
	.sign()

JWT解析

String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." +
	"eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9." +
	"536690902d931d857d2f47d337ec81048ee09a8e71866bcc8404edbbcbf4cc40";

JWT jwt = JWT.of(rightToken);

// JWT
jwt.getHeader(JWTHeader.TYPE);
// HS256
jwt.getHeader(JWTHeader.ALGORITHM);

// 1234567890
jwt.getPayload("sub");
// looly
jwt.getPayload("name");
// true
jwt.getPayload("admin");

JWT验证

  1. 验证签名
String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." +
	"eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9." +
	"536690902d931d857d2f47d337ec81048ee09a8e71866bcc8404edbbcbf4cc40";

// 密钥
byte[] key = "1234567890".getBytes();

// 默认验证HS265的算法
JWT.of(rightToken).setKey(key).verify()
  1. 详细验证

除了验证签名,Hutool提供了更加详细的验证:validate,主要包括:

  • Token是否正确
  • 生效时间不能晚于当前时间
  • 失效时间不能早于当前时间
  • 签发时间不能晚于当前时间

使用方式如下:

String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJNb0xpIiwiZXhwIjoxNjI0OTU4MDk0NTI4LCJpYXQiOjE2MjQ5NTgwMzQ1MjAsInVzZXIiOiJ1c2VyIn0.L0uB38p9sZrivbmP0VlDe--j_11YUXTu3TfHhfQhRKc";

byte[] key = "1234567890".getBytes();
boolean validate = JWT.of(token).setKey(key).validate(0);

其他自定义详细验证见JWT验证-JWTValidator章节。