JWT

JSON Web Token (https://jwt.io/)

组成

  • Header 头
  • Payload 有效载荷
  • Signature 签名

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

前两部分为JSON进行了Base64编码。

签名防止数据被篡改(修改任意一位则校验不通过)

具体使用

Github主页:

io.jsonwebtoken: https://github.com/jwtk/jjwt

0.12.3

工具类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class JwtUtils {
/**
* 生成JWT
*
* @param secretString 加密密码/秘钥
* @param claims Payload 数据
* @return 解析生成好的Jwt
*/
public static String genJwt(String secretString, Map<String, Object> claims) {

// 生成 SecretKey 根据秘钥
SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));

String jwt = Jwts.builder()
.signWith(key, Jwts.SIG.HS256) // 参数:SecretKey,加密方式
.expiration(new Date(System.currentTimeMillis() + 10 * 60 * 1000)) // 十分钟有效期
.claims(claims) // Payload 数据
.compact();

return jwt;
}

/**
* 解析 JWT
*
* @param secretString 密码/秘钥
* @param jwt 需要解析的 JWT
* @return 解析完成后的 Claims 对象
*/
public static Claims parseJwt(String secretString, String jwt) {

// 生成 SecretKey 根据秘钥
SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));

Claims claims = Jwts.parser()
.verifyWith(key) // 参数:SecretKey
.build() // JwtParser
.parseSignedClaims(jwt) // Jws<Claims>
.getPayload();

return claims;
}
}

旧版本

下列为 0.9.1 的旧版,不适用于新版,新版使用看Github页面

Maven依赖

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>

此依赖在高版本JDK需要额外引入一个依赖:

1
2
3
4
5
6
<!--        运行此JWT需要的包 高版本Java不包含,需要手动引入-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>

生成 JWT

秘钥过短会报错

1
2
3
4
5
6
7
8
9
Map<String, Object> claims = new HashMap<>();
claims.put("id", 1);
claims.put("name", "tom");

String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, key) // 签名算法
.setClaims(claims) // Payload 自定义内容
.setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000)) // 有效期
.compact();

解析 JWT

1
2
3
4
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwt)
.getBody();

parseClaimsJwt 方法适用于未签名的 JWT。
parseClaimsJws 方法适用于带有 JWS 签名的 JWT。

claims.toString() 输出