侧边栏壁纸
  • 累计撰写 57 篇文章
  • 累计创建 23 个标签
  • 累计收到 4 条评论

JWT极速入门

cluski
2022-04-01 / 0 评论 / 0 点赞 / 154 阅读 / 5,753 字
温馨提示:
本文最后更新于 2022-04-01,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

什么是 JWT?

JSON Web Token,通过数字签名的方式,以 ISON 对象为载体,在不同的服务终端之间安全的传输信息。

JWT有什么用?

JWT 最常见的场景就是授权认证,一旦用户登录,后续每个请求都将包含JWT,系统在每次处理用户请求的之前,都要先进行 JWT 安全校验,通过之后再进行处理。

JWT 的组成

JWT 由 3 部分组成,用.拼接

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

这三部分分别是:

  • Header
 {
    "typ": "JWT",
    "alg": "HS256"
}
  • Payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
  • Signature
var encodedstring = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret')

代码演示

依赖

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

测试

package top.cluski.jjwtdemo;

import cn.hutool.jwt.JWTUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.Base64Codec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

@SpringBootTest
public class JJwtDemoTests {

    /**
     * 创建token
     */
    @Test
    public void testCreateToken() {
        JwtBuilder jwtBuilder = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                // 声明的标识{"jti":"8888"}
                .setId("8888")
                // 主题,用户{"sub":"Rose"}
                .setSubject("Rose")
                // 创建日期{"ita":"xxx"}
                .setIssuedAt(new Date())
                // 设定盐
                .signWith(SignatureAlgorithm.HS256, "wangyf");
        // 获取jwt的token
        String token = jwtBuilder.compact();
        System.out.println(token);

        System.out.println("============================");
        String[] split = token.split("\\.");
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        // 签名是无法解密的
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

    /**
     * 解析token
     */
    @Test
    public void testParseToken() {
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY0ODgyMDExMn0.nWbSY58EE7lq2YWBPjNq8JkkAg9rzAuq0r-f-7XpH18";
        // 解析token,获取负载中声明的对象
        Claims claims = Jwts.parser()
                .setSigningKey("wangyf")
                .parseClaimsJws(token)
                .getBody();
        System.out.println("id: " + claims.getId());
        System.out.println("subject: " + claims.getSubject());
        System.out.println("issueAt: " + claims.getIssuedAt());
    }

    /**
     * 创建token (失效时间)
     */
    @Test
    public void testCreateTokenExp() {
        long now = System.currentTimeMillis();
        long exp = now + 60 * 1000;
        JwtBuilder jwtBuilder = Jwts.builder()
                // 声明的标识{"jti":"8888"}
                .setId("8888")
                // 主题,用户{"sub":"Rose"}
                .setSubject("Rose")
                // 创建日期{"ita":"xxx"}
                .setIssuedAt(new Date())
                // 设定盐
                .signWith(SignatureAlgorithm.HS256, "wangyf")
                // 设置过期时间
                .setExpiration(new Date(exp));
        // 获取jwt的token
        String token = jwtBuilder.compact();
        System.out.println(token);

        System.out.println("============================");
        String[] split = token.split("\\.");
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        // 签名是无法解密的
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

    /**
     * 解析token (失效时间)
     */
    @Test
    public void testParseTokenExp() {
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY0ODgyMDYxNywiZXhwIjoxNjQ4ODIwNjc3fQ.88MP33KYfELb2dIjyNPKRBMhatNKAqSC_sIVZrY8_CY";
        // 解析token,获取负载中声明的对象
        Claims claims = Jwts.parser()
                .setSigningKey("wangyf")
                .parseClaimsJws(token)
                .getBody();
        System.out.println("id: " + claims.getId());
        System.out.println("subject: " + claims.getSubject());
        System.out.println("issueAt: " + claims.getIssuedAt());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("签发时间" + simpleDateFormat.format(claims.getIssuedAt()));
        System.out.println("过期时间" + simpleDateFormat.format(claims.getExpiration()));
        System.out.println("当前时间" + simpleDateFormat.format(new Date()));
    }


    /**
     * 创建token (自定义声明)
     */
    @Test
    public void testCreateTokenByClaims() {
        long now = System.currentTimeMillis();
        long exp = now + 60 * 1000;
        JwtBuilder jwtBuilder = Jwts.builder()
                // 声明的标识{"jti":"8888"}
                .setId("8888")
                // 主题,用户{"sub":"Rose"}
                .setSubject("Rose")
                // 创建日期{"ita":"xxx"}
                .setIssuedAt(new Date())
                // 设定盐
                .signWith(SignatureAlgorithm.HS256, "wangyf")
                // 设置过期时间
                .setExpiration(new Date(exp))
                // 自定义声明
                .claim("roles", "admin")
                .claim("log", "xxx.jpg");
        // 获取jwt的token
        String token = jwtBuilder.compact();
        System.out.println(token);

        System.out.println("============================");
        String[] split = token.split("\\.");
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        // 签名是无法解密的
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

    /**
     * 解析token (自定义声明)
     */
    @Test
    public void testParseTokenByClaims() {
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY0ODgyMTA5NSwiZXhwIjoxNjQ4ODIxMTU1LCJyb2xlcyI6ImFkbWluIiwibG9nIjoieHh4LmpwZyJ9.rasA_qD27R_M1NvVs2qdU0QZKOG6-dttYDoQFDES6fc";
        // 解析token,获取负载中声明的对象
        Claims claims = Jwts.parser()
                .setSigningKey("wangyf")
                .parseClaimsJws(token)
                .getBody();
        System.out.println("id: " + claims.getId());
        System.out.println("subject: " + claims.getSubject());
        System.out.println("issueAt: " + claims.getIssuedAt());
        System.out.println("roles: " + claims.get("roles"));
        System.out.println("log: " + claims.get("log"));
    }

}

0

评论区