JJWT的介绍和使用
JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。
官方文档:
创建TOKEN
(1)依赖引入
在parent项目中的pom.xml中添加依赖:
<!--鉴权-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
(2)创建测试
在common的/test/java下创建测试类,并设置测试方法
public class JwtTest {
/****
* 创建Jwt令牌
*/
@Test
public void testCreateJwt(){
JwtBuilder builder= Jwts.builder()
.setId("888") //设置唯一编号
.setSubject("小白") //设置主题 可以是JSON数据
.setIssuedAt(new Date()) //设置签发日期
.signWith(SignatureAlgorithm.HS256,"leon");//设置签名 使用HS256算法,并设置SecretKey(字符串)
//构建 并返回一个字符串
System.out.println( builder.compact() );
}
}
运行打印结果:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NjIwNjIyODd9.RBLpZ79US
MplQyfJCZFD2muHV_KLks7M1ZsjTu6Aez4
再次运行,会发现每次运行的结果是不一样的,因为我们的载荷中包含了时间。
TOKEN解析
我们刚才已经创建了token ,在web应用中这个操作是由服务端进行然后发给客户端,客户端在下次向服务端发送请求时需要携带这个token(这就好像是拿着一张门票一样),那服务端接到这个token 应该解析出token中的信息(例如用户id),根据这些信息查询数据库返回相应的结果。
/***
* 解析Jwt令牌数据
*/
@Test
public void testParseJwt(){
String compactJwt="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NjIwNjIyODd9.RBLpZ79USMplQyfJCZFD2muHV_KLks7M1ZsjTu6Aez4";
Claims claims = Jwts.parser().
setSigningKey("leon").
parseClaimsJws(compactJwt).
getBody();
System.out.println(claims);
}
运行打印效果:
{jti=888, sub=小白, iat=1562062287}
试着将token或签名秘钥篡改一下,会发现运行时就会报错,所以解析token也就是验证token.
设置过期时间
有很多时候,我们并不希望签发的token是永久生效的,所以我们可以为token添加一个过期时间。
token过期设置
解释:
.setExpiration(date)//用于设置过期时间 ,参数为Date类型数据
运行,打印效果如下:
eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NjIwNjI5MjUsImV4cCI6MT
U2MjA2MjkyNX0._vs4METaPkCza52LuN0-2NGGWIIO7v51xt40DHY1U1Q
解析TOKEN
/***
* 解析Jwt令牌数据
*/
@Test
public void testParseJwt(){
String compactJwt="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NjIwNjI5MjUsImV4cCI6MTU2MjA2MjkyNX0._vs4METaPkCza52LuN0-2NGGWIIO7v51xt40DHY1U1Q";
Claims claims = Jwts.parser().
setSigningKey("leon").
parseClaimsJws(compactJwt).
getBody();
System.out.println(claims);
}
当前时间超过过期时间,则会报错。
自定义claims
我们刚才的例子只是存储了id和subject两个信息,如果你想存储更多的信息(例如角色)可以定义自定义claims。
创建测试类,并设置测试方法:
创建token:
@Test
public void createJwt(){
long currentTimeMillis = System.currentTimeMillis();
long l = currentTimeMillis + 20000;
//生成令牌
//创建jwtbuilder
JwtBuilder builder = Jwts.builder();
//1.头(不设置,默认) 2 载荷(数据) 3. 签名
builder.setId("唯一的标识")
.setIssuer("颁发者")//生成令牌的一方
.setSubject("主题")//就是描述 jwt的信息
.setExpiration(new Date(l))//设置过期时间
.signWith(SignatureAlgorithm.HS256,"leon");//设置签名
//3.可以自定义载荷
Map<String, Object> map = new HashMap<>();
map.put("myaddress","cn");
map.put("mycity","sz");
builder.addClaims(map);
//生成令牌
String compact = builder.compact();
System.out.println(compact);
}
解析TOKEN:
@Test
public void parseJwt(){
//String st = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiLllK_kuIDnmoTmoIfor4YiLCJpc3MiOiLpooHlj5HogIUiLCJzdWIiOiLkuLvpopgifQ.AU33UoJ8Vz_ZoCtKcvCEm5R0UFknLE-06E49z1h0nfI";
//String st = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiLllK_kuIDnmoTmoIfor4YiLCJpc3MiOiLpooHlj5HogIUiLCJzdWIiOiLkuLvpopgiLCJteWNpdHkiOiJzeiIsIm15YWRkcmVzcyI6ImNuIn0.VbuggDeIH66QlRAWGxoWPIKaRkCZOy45G-hAyz0Nq_k";
String st = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiLllK_kuIDnmoTmoIfor4YiLCJpc3MiOiLpooHlj5HogIUiLCJzdWIiOiLkuLvpopgiLCJleHAiOjE1NjY5ODU0NTMsIm15Y2l0eSI6InN6IiwibXlhZGRyZXNzIjoiY24ifQ.KtmMC-Hu1qlmYQgmLphoITQSZWRVv8YDssLZURKyczY";
//解析令牌
Jws<Claims> leon = Jwts.parser()
.setSigningKey("leon")
.parseClaimsJws(st);
System.out.println(leon.getBody());
}