Spring Boot中的JWT Token自动续期
引言
在现代Web应用程序中,JSON Web Tokens(JWT)被广泛用于身份验证和授权。由于JWT是无状态的,它在生成后通常会有一个固定的有效期限。为了提升用户体验,应用程序通常需要实现JWT token的自动续期功能。本文将介绍如何在Spring Boot中实现JWT token的自动续期。
JWT的基本原理
JWT是一种开放标准(RFC 7519),用于在网络应用环境间以JSON对象安全地传递信息。JWT是由三部分组成的字符串,以.
分隔:头部、载荷和签名。
- 头部(Header):一般由令牌的类型(JWT)和签名算法(如HS256)组成。
- 载荷(Payload):包含声明(Claims),一些是注册声明,包含用户信息。
- 签名(Signature):为了验证JWT的发送者是他所声称的,并确保消息在传输过程中没有被篡改。
实现JWT自动续期
在我们的实现中,用户每次请求都会验证Token的有效性。如果Token接近过期或者已经过期,我们将返回一个新的Token。具体步骤如下:
- 创建Token:用户成功登录后生成JWT。
- 验证Token:每次请求时校验token的有效性。
- 续期Token:在必要时(例如Token即将过期)生成新的Token。
下面是JWT token的生成和续期的代码示例。
1. Maven依赖配置
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2. JWT工具类
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtil {
private final String SECRET_KEY = "mySecretKey";
private final long EXPIRATION_TIME = 1000 * 60 * 15; // 15分钟
public String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, username);
}
private String createToken(Map<String, Object> claims, String subject) {
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public boolean validateToken(String token, String username) {
final String extractedUsername = extractUsername(token);
return (extractedUsername.equals(username) && !isTokenExpired(token));
}
public String extractUsername(String token) {
return extractAllClaims(token).getSubject();
}
private Claims extractAllClaims(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}
private boolean isTokenExpired(String token) {
return extractAllClaims(token).getExpiration().before(new Date());
}
public String refreshToken(String token) {
if (isTokenExpired(token)) {
return null; // Token已经过期,无法续期
}
String username = extractUsername(token);
return generateToken(username); // 生成新的Token
}
}
3. 续期逻辑示例
@RestController
@RequestMapping("/api")
public class AuthController {
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public ResponseEntity<String> login(@RequestBody AuthRequest authRequest) {
// 这里省略用户身份验证逻辑
String token = jwtUtil.generateToken(authRequest.getUsername());
return ResponseEntity.ok(token);
}
@GetMapping("/refresh-token")
public ResponseEntity<String> refreshToken(@RequestHeader("Authorization") String token) {
String newToken = jwtUtil.refreshToken(token.replace("Bearer ", ""));
if (newToken == null) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Token已经过期,无法续期");
}
return ResponseEntity.ok(newToken);
}
}
4. 状态图
接下来,我们用状态图展示JWT Token的生命周期:
stateDiagram
[*] --> Token生成
Token生成 --> Token有效
Token有效 --> Token检查
Token检查 --> Token续期 : Token接近过期
Token检查 --> Token无效 : Token过期
Token续期 --> Token有效
Token无效 --> [*]
结尾
本文介绍了如何在Spring Boot中实现JWT token的自动续期功能。通过设计合适的JWT工具类,我们能够在用户的Token快要过期时主动进行续期,以提升用户的使用体验。同时,应用程序在实现安全功能时,也需要关注Token的生命周期管理。希望本文对您在使用JWT进行身份验证时有所帮助!