每一秒钟的时间都值得铭记

0%

Jwt封装工具类

一、引入依赖

首先,我们需要引入SpringBoot和Jwt相关的,其中jjwt是Java语言编写的一个Jwt实现依赖,里面封装了大量和Jwt相关的操作,我们可以直接使用。

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
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<jjwt.version>0.9.0</jjwt.version>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<relativePath/>
</parent>

<dependencies>
<!--SpringMVC的启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--jjwt,Java对JWT的封装工具依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!--Spring单元测试的启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombox的依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>

二、Jwt相关参数

在封装Jwt工具类之前,我们先将一个属性配置在yml文件中,并使用SpringBoot的@ConfigurationProperties注解注入Java类的属性中。

1
2
3
4
5
6
7
8
zero:
sys:
security:
jwt:
secret: HdGkiOiI4ODgiLCJzdWIiOiLlsI
ttl: 3600000
issuer: https://www.zero.com
name: accessToken
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
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "zero.sys.security.jwt")
public class JwtProperties {

/**
* JWT加密秘钥信息
*/
private String secret;

/**
* Token过期时间,默认为1个小时
*/
private Long ttl;

/**
* token的签发者
*/
private String issuer;

/**
* token名称;accessToken
*/
private String name;

}

三、Jwt封装工具类

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
@Component
public class JwtUtils {

private static JwtProperties jwtProperties;

@Autowired
public void setJwtProperties(JwtProperties jwtProperties) {
JwtUtils.jwtProperties = jwtProperties;
}

private static ObjectMapper objectMapper;

@Autowired
public static void setObjectMapper(ObjectMapper objectMapper) {
JwtUtils.objectMapper = objectMapper;
}

/**
* 由字符串生成加密key
*
* @return 返回一个加密的字符串数据
* @throws Exception 抛出异常
*/
private static SecretKey generateKey() throws Exception {
String secret = jwtProperties.getSecret();
// 本地的密码解码
byte[] encodedKey = Base64.decodeBase64(secret);
// 根据给定的字节数组使用AES加密算法构造一个密钥
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}

/**
* 创建JWT
*
* @param id JWT的ID
* @param subject JWT主体信息,一般以Json格式的数据存储
* @param issuer JWT签发者
* @param ttlMillis JWT的有效时间,单位是毫秒
* @param claims 创建payload的私有声明,也就是自定义的JWT信息
* @return 返回JWT
* @throws Exception 抛出异常
*/
public static String createJWT(String id, String subject, String issuer, Long ttlMillis, Map<String, Object> claims) throws Exception {
// 指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了。
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 生成签名的时候使用的秘钥secret,切记这个秘钥不能外露哦。它就是你服务端的私钥,在任何场景都不应该流露出去,一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
SecretKey key = generateKey();

// 下面就是在为payload添加各种标准声明和私有声明了,这里其实就是new一个JwtBuilder,设置jwt的body
JwtBuilder builder = Jwts.builder();
// 设置签名使用的签名算法和签名使用的秘钥
builder.signWith(signatureAlgorithm, key);
// jti:设置JWT的ID,是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击
builder.setId(id);
// iat:JWT的签发时间,生成JWT的时间
builder.setIssuedAt(new Date());
// iss:jwt签发人
builder.setIssuer(issuer);
// sub:代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放用户信息的,作为什么用户的唯一标志
builder.setSubject(subject);
if (ObjectUtils.allNotNull(claims)) {
// 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
builder.setClaims(claims);
}

// exp:设置过期时间
if (ttlMillis >= 0) {
Long expiredMillis = System.currentTimeMillis() + ttlMillis;
Date expiredDate = new Date(expiredMillis);
builder.setExpiration(expiredDate);
}
return builder.compact();
}

/**
* 创建JWT,默认配置了issuer(JWT签发者)
*
* @param id JWT的ID
* @param subject JWT主体信息,一般以Json格式的数据存储
* @param ttlMillis JWT的有效时间,单位是毫秒
* @param claims 创建payload的私有声明,也就是自定义的JWT信息
* @return 返回JWT
* @throws Exception 抛出异常
*/
public static String createJWT(String id, String subject, Long ttlMillis, Map<String, Object> claims) throws Exception {
return createJWT(id, subject, jwtProperties.getIssuer(), ttlMillis, claims);
}

/**
* 创建JWT,默认配置了issuer(JWT签发者),ttlMillis(有效时间)
*
* @param id JWT的ID
* @param subject JWT主体信息,一般以Json格式的数据存储
* @param claims 创建payload的私有声明,也就是自定义的JWT信息
* @return 返回JWT
* @throws Exception 抛出异常
*/
public static String createJWT(String id, String subject, Map<String, Object> claims) throws Exception {
return createJWT(id, subject, jwtProperties.getIssuer(), jwtProperties.getTtl(), claims);
}

/**
* 创建JWT,默认配置了issuer(JWT签发者),ttlMillis(有效时间),默认claims为null
*
* @param id JWT的ID
* @param subject JWT主体信息,一般以Json格式的数据存储
* @return 返回JWT
* @throws Exception 抛出异常
*/
public static String createJWT(String id, String subject) throws Exception {
return createJWT(id, subject, jwtProperties.getIssuer(), jwtProperties.getTtl(), null);
}

/**
* 解密JWT,如果秘钥错误,或者JWT被修改过,会直接抛出异常信息
*
* @param jwt JWT字符串信息
* @return 返回JWT载荷信息
* @throws Exception 抛出异常
*/
public static Claims parseJWT(String jwt) throws Exception {
// 签名秘钥,和生成的签名的秘钥一模一样
SecretKey key = generateKey();
// 得到DefaultJwtParser
Claims claims = Jwts.parser()
// 设置签名的秘钥
.setSigningKey(key)
// 设置需要解析的jwt
.parseClaimsJws(jwt).getBody();
return claims;
}


/**
* 判断jwt是否已经过期
*
* @param jwt JWT字符串信息
* @return 如果jwt已经过期,返回true,否则返回false
* @throws Exception 抛出异常
*/
public static boolean isExpiration(String jwt) throws Exception {
Claims claims = JwtUtils.parseJWT(jwt);
return claims.getExpiration().before(new Date());
}
}

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------这是我的底线^_^-------------