JWT令牌安全实践详解一、JWT概述JSON Web TokenJWT是一种用于安全传输信息的开放标准RFC 7519。1.1 JWT结构┌─────────────────────────────────────────────────────────────┐ │ JWT Token │ ├─────────────────────────────────────────────────────────────┤ │ Header.Payload.Signature │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ {alg:HS256, {sub:123, HMACSHA256( │ │ typ:JWT} name:John, base64Url(header). │ │ exp:1704067200) . │ │ base64Url(payload),│ │ secret) │ └─────────────────────────────────────────────────────────────┘1.2 JWT组成部分部分说明编码方式Header算法和类型Base64UrlPayload声明信息Base64UrlSignature签名HMAC/RSA二、JWT实现2.1 创建JWTimport io.jsonwebtoken.*; import java.util.Date; public class JwtUtil { private static final String SECRET_KEY your-256-bit-secret-key; private static final long EXPIRATION_TIME 86400000; // 24小时 public static String generateToken(String userId, String username) { return Jwts.builder() .setSubject(userId) .claim(username, username) .claim(role, admin) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() EXPIRATION_TIME)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } }2.2 验证JWTpublic static Claims validateToken(String token) { try { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody(); } catch (JwtException | IllegalArgumentException e) { throw new RuntimeException(Invalid token, e); } }2.3 刷新Tokenpublic static String refreshToken(String token) { Claims claims validateToken(token); claims.setIssuedAt(new Date()); claims.setExpiration(new Date(System.currentTimeMillis() EXPIRATION_TIME)); return Jwts.builder() .setClaims(claims) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); }三、JWT安全配置3.1 密钥管理// 使用256位以上的密钥 private static final String SECRET_KEY generateSecureKey(); private static String generateSecureKey() { SecureRandom random new SecureRandom(); byte[] key new byte[32]; // 256 bits random.nextBytes(key); return Base64.getEncoder().encodeToString(key); }3.2 使用RSA非对称加密// 生成RSA密钥对 KeyPairGenerator keyGen KeyPairGenerator.getInstance(RSA); keyGen.initialize(2048); KeyPair keyPair keyGen.generateKeyPair(); // 使用私钥签名 String token Jwts.builder() .setSubject(user123) .signWith(keyPair.getPrivate(), SignatureAlgorithm.RS256) .compact(); // 使用公钥验证 Claims claims Jwts.parser() .setSigningKey(keyPair.getPublic()) .parseClaimsJws(token) .getBody();3.3 设置合理的过期时间// 访问Token短过期时间 private static final long ACCESS_TOKEN_EXPIRE 15 * 60 * 1000; // 15分钟 // 刷新Token长过期时间 private static final long REFRESH_TOKEN_EXPIRE 7 * 24 * 60 * 60 * 1000; // 7天四、安全最佳实践4.1 Token存储策略存储位置优点缺点适用场景LocalStorage方便访问XSS风险单页应用SessionStorage会话级存储页面切换丢失临时数据HttpOnly CookieXSS安全CSRF风险传统WebMemory最安全页面刷新丢失高安全场景4.2 CSRF防护// Spring Security配置 http.csrf(csrf - csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .ignoringRequestMatchers(/api/**) );4.3 XSS防护!-- 设置HttpOnly和Secure标志 -- Set-Cookie: JWTtoken; HttpOnly; Secure; SameSiteStrict五、Token黑名单机制5.1 基于Redis的黑名单public class TokenBlacklist { private final StringRedisTemplate redisTemplate; private static final String PREFIX blacklist:; public void invalidateToken(String token, long expireSeconds) { String key PREFIX token; redisTemplate.opsForValue().set(key, true, expireSeconds, TimeUnit.SECONDS); } public boolean isBlacklisted(String token) { String key PREFIX token; return Boolean.TRUE.equals(redisTemplate.hasKey(key)); } }5.2 拦截器验证public class JwtInterceptor implements HandlerInterceptor { private final TokenBlacklist blacklist; Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token extractToken(request); if (blacklist.isBlacklisted(token)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } // 继续验证token return true; } }六、JWT vs Session对比特性JWTSession状态无状态有状态存储客户端服务端扩展性好差安全性需额外处理相对安全性能网络传输大服务器内存七、安全检查清单7.1 必做检查检查项说明使用HTTPS防止Token被窃取设置过期时间限制Token有效期避免敏感信息Payload是Base64编码不是加密使用强密钥256位以上密钥验证签名防止Token被篡改7.2 推荐检查检查项说明实现刷新机制定期轮换Token实现黑名单支持主动注销限制Token大小避免过大Payload监控异常行为检测暴力破解八、总结JWT是一种强大的身份认证机制但需要正确使用才能保证安全使用HTTPS始终通过HTTPS传输Token合理设置过期时间访问Token短刷新Token长使用非对称加密避免密钥泄露风险实现黑名单机制支持主动注销存储在安全位置根据场景选择存储方式通过以上措施可以构建安全可靠的JWT认证系统。