-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJwtUtils.java
More file actions
120 lines (102 loc) · 3.31 KB
/
JwtUtils.java
File metadata and controls
120 lines (102 loc) · 3.31 KB
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
package com.example.demo.util;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import javax.crypto.SecretKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
/**
* https://github.com/jwtk/jjwt#jws-create-key
*/
@Component
public class JwtUtils {
// HS256
SecretKey key = Jwts.SIG.HS256.key().build();
// 2小时
private Long accessTokenExpiration = 7200000L;
// 7天
private Long refreshTokenExpiration = 604800000L;
private static final String TOKEN_BLACKLIST_PREFIX = "token:blacklist:";
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public String generateAccessToken(UserDetails userDetails) {
return generateToken(userDetails, accessTokenExpiration);
}
public String generateRefreshToken(UserDetails userDetails) {
return generateToken(userDetails, refreshTokenExpiration);
}
private String generateToken(UserDetails userDetails, long expiration) {
String username = userDetails.getUsername();
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
String jws = Jwts.builder().subject(username).expiration(expirationDate).signWith(key).compact();
return jws;
}
/**
* Returns the username from the given JWT token.
*
* @param token the JWT token
* @return the username
*/
public String getUsernameFromToken(String token) {
return Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload().getSubject();
}
/**
* Validate a JWT token. This method parses the given JWT token, using the
* previously set secret key, and verifies its signature.
*
* @param token the JWT token to be validated
* @return true if the token is valid, false otherwise
*/
public boolean validateToken(String token) {
try {
Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
return true;
} catch (JwtException e) {
return false;
}
}
public boolean isTokenBlacklisted(String token) {
return Boolean.TRUE.equals(redisTemplate.hasKey(TOKEN_BLACKLIST_PREFIX + token));
}
public void addToBlacklist(String token) {
// 获取token的过期时间
Date expiration = getExpirationDateFromToken(token);
long ttl = expiration.getTime() - System.currentTimeMillis();
if (ttl > 0) {
redisTemplate.opsForValue().set(
TOKEN_BLACKLIST_PREFIX + token,
"blacklisted",
ttl,
TimeUnit.MILLISECONDS);
}
}
public Date getExpirationDateFromToken(String token) {
Claims claims = Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload();
return claims.getExpiration();
}
/**
* 判断是否是refresh token
*
* @param token
* @return
*/
public boolean isRefreshToken(String token) {
try {
Claims claims = Jwts.parser()
.verifyWith(key)
.build()
.parseSignedClaims(token)
.getPayload();
// 通过过期时间判断是否是refresh token(根据业务逻辑调整)
long expiration = claims.getExpiration().getTime();
long current = System.currentTimeMillis();
return (expiration - current) > accessTokenExpiration;
} catch (JwtException e) {
return false;
}
}
}