JJWT的介绍和使用

JJWT是一个提供端到端的JWT创建和验证的Java库。永远免费和开源(Apache License,版本2.0),JJWT很容易使用和理解。它被设计成一个以建筑为中心的流畅界面,隐藏了它的大部分复杂性。

官方文档:

https://github.com/jwtk/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());


}

 

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐