保证 Java 登录 Token 永不失效的方案
问题描述
在开发 Web 应用时,用户登录后会生成一个 Token,用于标识用户身份和权限。然而,由于 Token 的失效时间限制,用户在一定时间内没有操作,Token 就会失效,需要重新登录。如何保证 Token 永不失效,是一个需要解决的问题。
解决方案
一种常用的解决方案是通过刷新 Token 的方式来延长 Token 的有效期。当用户在一定时间内有操作时,会刷新 Token 的过期时间,从而实现 Token 的永不失效。
实现步骤
- 当用户登录成功后,生成 Token 并设置过期时间,同时生成一个 Refresh Token,用于刷新 Token。
- 在用户每次操作时,刷新 Token 的过期时间。
- 当 Token 过期时,用户可以使用 Refresh Token 来获取新的 Token。
代码示例
public class TokenUtil {
private static final long EXPIRATION_TIME = 15 * 60 * 1000; // Token 过期时间 15 分钟
private static final long REFRESH_EXPIRATION_TIME = 24 * 60 * 60 * 1000; // Refresh Token 过期时间 24 小时
private static final String SECRET = "your_secret_key";
public static String generateToken(User user) {
Date expirationDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
return Jwts.builder()
.setSubject(user.getUsername())
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public static String generateRefreshToken(User user) {
Date expirationDate = new Date(System.currentTimeMillis() + REFRESH_EXPIRATION_TIME);
return Jwts.builder()
.setSubject(user.getUsername())
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public static String refreshExpiredToken(String token) {
Claims claims = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
Date expirationDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
return Jwts.builder()
.setClaims(claims)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public static boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
在上述代码示例中,我们使用了 JWT (JSON Web Tokens) 来生成 Token 和 Refresh Token,并设置了过期时间。当用户操作时,调用 refreshExpiredToken
方法来刷新 Token 的过期时间。
关系图
erDiagram
USER ||--o TOKEN : has
USER ||--o REFRESH_TOKEN : has
结论
通过刷新 Token 的方式来延长 Token 的过期时间,可以保证 Token 永不失效。在实际应用中,可以根据具体需求和安全性要求来调整 Token 和 Refresh Token 的过期时间,以达到最佳的用户体验和安全性保障。