JJwt与token 二

  • Post author:
  • Post category:其他


  1. jjwt介绍

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

    官网:https://github.com/jwtk/jjwt

  2. 使用

    新建项目引入依赖

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

测试类

package com.srr;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;

@SpringBootTest
class SpringSecurityDemo01demoApplicationTests {

    @Test
    void test1() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("3070") //设置id
                .setSubject("测试jwt") //主题
                .setIssuedAt(new Date())// 签发日期
                .signWith(SignatureAlgorithm.HS256, "srrsrr");//设置算法和盐
        String jwt = jwtBuilder.compact();
        System.out.println("jwt = "+jwt);
    }

}

运行结果

运行结果第一次
jwt = eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIzMDcwIiwic3ViIjoi5rWL6K-Vand0IiwiaWF0IjoxNjc5OTEwMTc2fQ.pIA4py2vaZcpgW5s_TjCT7AA-UGscYfwvDp8UP9ijhw
运行结果第一次
jwt = eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIzMDcwIiwic3ViIjoi5rWL6K-Vand0IiwiaWF0IjoxNjc5OTEwMjMxfQ.VyIg6ekewT0bOF4U4ksXHHCdTPQYKQnG515nqj-nlNE

发现每次运行的结果不一样,因为我们的载荷中包含了时间

  1. 解析jwt

    刚才已经创建了token,在web应用中这个操作是由服务端进行然后发给客户端,客户端在下次向服务 端发送请求时需要 携带这个jwt字符串,也就是token,那服务端拉到这个token应该解析出token中的信息,如id,根据这些信息查询数据库返回相应的结果
package com.srr;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;

@SpringBootTest
class SpringSecurityDemo01demoApplicationTests {

    @Test
    void test1() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("3070") //设置id
                .setSubject("测试jwt") //主题
                .setIssuedAt(new Date())// 签发日期
                .signWith(SignatureAlgorithm.HS256, "srrsrr");//设置算法和密钥
        String jwt = jwtBuilder.compact();
        System.out.println("jwt = "+jwt);
		//解析token
        Claims claims = Jwts.parser().setSigningKey("srrsrr").parseClaimsJws(jwt).getBody();
        System.out.println(claims);
    }

}

结果

{jti=3070, sub=测试jwt, iat=1679910666}

注意1:尝试将token或签名秘钥篡改一下,会发现运行时就报错,所以解析token也就是验证token

注意2: 设置签名key必须和生成时一致

  1. 设置过期时间

    很多的时候,我们并不希望签发的token是永久生效的,所以可以为token添加一个过期时间

    创建token并设置过期时间
package com.srr;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;

@SpringBootTest
class SpringSecurityDemo01demoApplicationTests {

    @Test
    void test1() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("3070") //设置id
                .setSubject("测试jwt") //主题
                .setIssuedAt(new Date())// 签发日期
                .signWith(SignatureAlgorithm.HS256, "srrsrr");//设置算法和密钥
        String jwt = jwtBuilder.compact();
        System.out.println("jwt = "+jwt);

        Claims claims = Jwts.parser().setSigningKey("srrsrr1").parseClaimsJws(jwt).getBody();
        System.out.println(claims);
    }


    @Test
    void test2() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("3070")  //设置id
                .setSubject("测试token过期")//主题
                .setIssuedAt(new Date())// 签发日期
                .setExpiration(new Date(System.currentTimeMillis() + 10000))// 过期时间(当前时间+10秒)
                .signWith(SignatureAlgorithm.HS256, "srr123"); //算法和盐

        String jwt = jwtBuilder.compact();
        System.out.println(jwt);
		 try {
            //睡15秒
            Thread.sleep(15000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
			
        //解析token
        Claims claims = Jwts.parser().setSigningKey("srr123").parseClaimsJws(jwt).getBody();
        System.out.println(claims);
    }
}

结果 报错

io.jsonwebtoken.ExpiredJwtException: JWT expired at 2023-03-27T18:10:13Z. Current time: 2023-03-27T18:10:18Z, a difference of 5489 milliseconds.  Allowed clock skew: 0 milliseconds.
...
Process finished with exit code -1
  1. 自定义claims

    上面我们只是存储了id和subject两个信息,如果想要存储更多,可以自定义claims
package com.srr;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Date;

@SpringBootTest
class SpringSecurityDemo01demoApplicationTests {

    @Test
    void test1() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("3070") //设置id
                .setSubject("测试jwt") //主题
                .setIssuedAt(new Date())// 签发日期
                .signWith(SignatureAlgorithm.HS256, "srrsrr");//设置算法和密钥
        String jwt = jwtBuilder.compact();
        System.out.println("jwt = "+jwt);

        Claims claims = Jwts.parser().setSigningKey("srrsrr1").parseClaimsJws(jwt).getBody();
        System.out.println(claims);
    }


    @Test
    void test2() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("3070")  //设置id
                .setSubject("测试token过期")//主题
                .setIssuedAt(new Date())// 签发日期
                .setExpiration(new Date(System.currentTimeMillis() + 10000))// 过期时间(当前时间+10秒)
                .signWith(SignatureAlgorithm.HS256, "srr123"); //算法和盐

        String jwt = jwtBuilder.compact();
        System.out.println(jwt);

        try {
            //睡15秒
            Thread.sleep(15000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //解析token
        Claims claims = Jwts.parser().setSigningKey("srr123").parseClaimsJws(jwt).getBody();
        System.out.println(claims);
    }

    @Test
    void test3() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId("3070") //设置Id
                .setSubject("测试自定义claims") //主题
                .setIssuedAt(new Date()) //签发日期
                .claim("userId", "001") //自定义 claim
                .setExpiration(new Date(System.currentTimeMillis() + 900000)) //过期时间
                .signWith(SignatureAlgorithm.HS256, "srrabc"); //算法 和密钥

        String jwt = jwtBuilder.compact(); //生成token
        System.out.println(jwt);

        //解析token
        Claims claims = Jwts.parser().setSigningKey("srrabc").parseClaimsJws(jwt).getBody();
        System.out.println(claims);
    }
}

运行结果

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIzMDcwIiwic3ViIjoi5rWL6K-V6Ieq5a6a5LmJY2xhaW1zIiwiaWF0IjoxNjc5OTEyMjA5LCJ1c2VySWQiOiIwMDEiLCJleHAiOjE2Nzk5MTMxMDl9.GTmVsrEZb8VO-RUyYyt5tCVptPdirsLOZFnk4dgRpPk
{jti=3070, sub=测试自定义claims, iat=1679912209, userId=001, exp=1679913109}



版权声明:本文为qq_39828220原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。