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); }