关于jwt:jwt生成token和token解析基础

6次阅读

共计 2157 个字符,预计需要花费 6 分钟才能阅读完成。

1.jwt 构造

jwt 生成到客户端 (浏览器) 的 token 蕴含 ”.” 离开的三个局部:

  • header(Base64Url 编码过的)
  • payload(Base64Url 编码过的)
  • signature

形如:xxxxx.yyyyy.zzzzz

1.1 例子:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYW5keSIsImV4cCI6MTY1NTg5NzEwMCwiYWdlIjozMH0.32hfc-oBxGg2Lgk3QR48HCbadsbOfCUxexw9aiQ_FQk

拆为 3 局部:

  • eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.(header)
  • eyJuYW1lIjoiYW5keSIsImV4cCI6MTY1NTg5NzEwMCwiYWdlIjozMH0.(payload)
  • 32hfc-oBxGg2Lgk3QR48HCbadsbOfCUxexw9aiQ_FQk(signature)

2.header+payload+signature 介绍

2.1 header

下面的 header 局部:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
base64Url 解码后:

{
  "typ": "JWT",
  "alg": "HS256"
}

通常阐明 token 的类型、生成 token 所应用的的算法

The header typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used, such as HMAC SHA256 or RSA.

2.2 Payload

下面的 Payload 局部:eyJuYW1lIjoiYW5keSIsImV4cCI6MTY1NTg5NzEwMCwiYWdlIjozMH0
base64Url 解码后:

{
  "name": "andy",
  "exp": 1655897100,
  "age": 30
}

通常是要客户端申请时带货的内容(比方用户名,比方是否是管理员等,server 端生成的时候能够定义内容,模式如 map)

The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data. There are three types of claims: registered, public, and private claims.

2.3 Signature

下面的 Signature 局部:32hfc-oBxGg2Lgk3QR48HCbadsbOfCUxexw9aiQ_FQk
它是用来验签的,验证是否被客户端批改过,它的生成逻辑如下:
就是应用 header 局部的 base64Url、payload 局部的 base64Url 局部、小圆点、以及你的私钥明码,应用指定的算法生成的;因为有明码,所以是平安的,这也是明码要爱护好的起因。

  • 计算逻辑如下:

    HMACSHA256(
    base64UrlEncode(header) + “.” + base64UrlEncode(payload),
    12345
    )

3. java 测试用例

    /**
     * JWT 加密生成 token, payload 中保留 name/age
     */
    @Test
    public void testJwtToken() {
        // 加密秘钥
        final String SECRET = "12345";

        Calendar c = Calendar.getInstance();
        c.add(Calendar.HOUR, 2);

        String token = JWT.create().withClaim("name", "andy")
                .withClaim("age", 30)
                .withExpiresAt(c.getTime())
                .sign(Algorithm.HMAC256(SECRET));

        System.out.println(token);
    }

    /**
     * JWT 解密生成 token, 读取 payload 中保留的 name/age
     */
    @Test
    public void testJwtVerify() {

        String jwtToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYW5keSIsImV4cCI6MTY1NTg4ODk3MiwiYWdlIjozMH0.LU4AQJkld03kDhatkiiArSJI4liGiANArTvoyswzk5I";
        final String SECRET = "12345";

        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT decodedJWT = verifier.verify(jwtToken);
        Claim name = decodedJWT.getClaim("name");
        Claim age = decodedJWT.getClaim("age");
        System.out.println(name);
        System.out.println(age);

    }
正文完
 0