Commit 757fc11b by zhangxingmin

push

parent beeb74f0
......@@ -5,6 +5,7 @@ import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecurityException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
......@@ -12,16 +13,14 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Collection;
import java.util.Date;
import java.util.Base64;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
* JWT令牌提供者
* 修复了密钥长度不足的问题,并优化了异常处理
*/
@Slf4j
@Component
public class JwtTokenProvider {
......@@ -40,6 +39,7 @@ public class JwtTokenProvider {
throw new JwtAuthenticationException("无法从空认证信息生成令牌");
}
log.info("jwtExpiration毫秒值:{}",jwtExpiration);
AuthUserDto authUserDto = (AuthUserDto) authentication.getPrincipal();
try {
......@@ -220,10 +220,117 @@ public class JwtTokenProvider {
.getHeader();
}
// 在 JwtTokenProvider 类中添加以下方法
/**
* 解析 JWT token 并获取过期时间
* 这个方法不需要 Spring 依赖注入,可以直接调用
*/
public static void analyzeToken(String token, String secretKey) {
try {
// 使用给定的密钥进行解析
byte[] keyBytes = Base64.getDecoder().decode(secretKey);
SecretKey key = Keys.hmacShaKeyFor(keyBytes);
// 解析 token
Jws<Claims> claimsJws = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token);
Claims claims = claimsJws.getBody();
System.out.println("Token 解析成功:");
System.out.println("Subject (用户ID): " + claims.getSubject());
System.out.println("Issued At (签发时间): " + new Date(claims.getIssuedAt().getTime()));
System.out.println("Expiration (过期时间): " + new Date(claims.getExpiration().getTime()));
System.out.println("Roles: " + claims.get("roles"));
// 计算剩余有效期
long currentTime = System.currentTimeMillis();
long expirationTime = claims.getExpiration().getTime();
long remainingTime = expirationTime - currentTime;
System.out.println("当前时间: " + new Date(currentTime));
System.out.println("距离过期还有: " + formatDuration(remainingTime));
} catch (ExpiredJwtException e) {
// 即使过期了,也能获取到 claims
Claims claims = e.getClaims();
System.out.println("Token 已过期:");
System.out.println("Subject (用户ID): " + claims.getSubject());
System.out.println("Issued At (签发时间): " + new Date(claims.getIssuedAt().getTime()));
System.out.println("Expiration (过期时间): " + new Date(claims.getExpiration().getTime()));
System.out.println("过期于: " + formatDuration(System.currentTimeMillis() - claims.getExpiration().getTime()) + "前");
} catch (Exception e) {
System.err.println("解析 Token 失败: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 格式化时间间隔
*/
private static String formatDuration(long millis) {
if (millis < 0) {
return "已过期 " + formatDuration(-millis);
}
long seconds = millis / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
if (days > 0) {
return days + "天 " + (hours % 24) + "小时";
} else if (hours > 0) {
return hours + "小时 " + (minutes % 60) + "分钟";
} else if (minutes > 0) {
return minutes + "分钟 " + (seconds % 60) + "秒";
} else {
return seconds + "秒";
}
}
/**
* 修改 main 方法,使用配置文件中的密钥
*/
public static void main(String[] args) {
// 生成一个符合HS512要求的密钥
System.out.println("请将以下生成的JWT密钥复制到配置文件中(application.yml或application.properties):");
System.out.println("jwt.secret: " + generateSecureKey());
System.out.println("jwt.expiration: 86400000 # 24小时");
// 使用配置文件中的密钥
String configSecret = "v92cuMDOZEd0WIbmX9LHQpZ0HgMIfRPXvDXGmP+5ThbADd2YdD0mCbGujIvLSBZR2ZWby8PKYRT2ReBQ7wIDPQ==";
// 要解析的 token
String token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyXzEwMDEiLCJyb2xlcyI6W10sImlhdCI6MTc2ODU2MTY5NywiZXhwIjoxNzY4NjQ4MDk3fQ.LMbTJE-lnWZn9YSNpgMH9tz298BAHJTtVBuahtZosklRnrnfUTaz3yurJpneMseDOybXjmxpPXeCErdmgdO8yw";
// 分析 token
System.out.println("使用配置文件中的密钥分析 Token:");
analyzeToken(token, configSecret);
System.out.println("\n--- 生成新的测试 Token ---");
// 使用配置文件中的密钥生成一个新的测试 token
try {
byte[] keyBytes = Base64.getDecoder().decode(configSecret);
SecretKey key = Keys.hmacShaKeyFor(keyBytes);
// 生成一个有效期更合理的测试 token(24小时)
long expiration = 1577847600000L; // 24小时
String newToken = Jwts.builder()
.setSubject("test_user_001")
.claim("roles", Arrays.asList("ROLE_USER"))
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(key, SignatureAlgorithm.HS512)
.compact();
System.out.println("新生成的 Token: " + newToken);
System.out.println("\n解析新生成的 Token:");
analyzeToken(newToken, configSecret);
} catch (Exception e) {
System.err.println("生成测试 Token 失败: " + e.getMessage());
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment