当前位置: 首页 > news >正文

Hutool JWT 教程

1. 添加依赖

<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.25</version> </dependency>

2. 基本使用

2.1 生成 JWT

import cn.hutool.jwt.JWT; import cn.hutool.jwt.JWTUtil; import java.util.HashMap; import java.util.Map; public class JwtDemo { // 密钥(实际使用中应配置在配置文件中) private static final String SECRET_KEY = "mySecretKey123456"; // 生成 JWT public static String generateToken(String userId, String username) { Map<String, Object> payload = new HashMap<>(); payload.put("userId", userId); payload.put("username", username); payload.put("role", "admin"); // 设置过期时间(单位:毫秒) long expireTime = System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000; // 7天 return JWT.create() .setPayload(payload) // 设置自定义载荷 .setIssuedAt(new Date()) // 签发时间 .setExpiresAt(new Date(expireTime)) // 过期时间 .setKey(SECRET_KEY.getBytes()) // 设置密钥 .sign(); // 签名并生成token } }

2.2 解析验证 JWT

// 验证 JWT public static boolean verifyToken(String token) { try { return JWT.of(token).setKey(SECRET_KEY.getBytes()).verify(); } catch (Exception e) { return false; } } // 解析 JWT 获取载荷 public static JWT parseToken(String token) { return JWT.of(token); } // 获取指定字段 public static Object getClaim(String token, String key) { return JWT.of(token).getPayload(key); }

3. 完整示例

import cn.hutool.jwt.JWT; import cn.hutool.jwt.JWTUtil; import cn.hutool.jwt.JWTValidator; import cn.hutool.jwt.signers.JWTSigner; import cn.hutool.jwt.signers.JWTSignerUtil; import java.util.Date; import java.util.HashMap; import java.util.Map; public class JwtExample { private static final String SECRET = "mySecretKey123!@#"; // 1. 创建 JWT public static String createJwt() { Map<String, Object> payload = new HashMap<>(); payload.put("uid", 10001); payload.put("name", "张三"); payload.put("email", "zhangsan@example.com"); // 使用 HS256 算法 JWTSigner signer = JWTSignerUtil.hs256(SECRET.getBytes()); String token = JWT.create() .setPayload(payload) .setIssuedAt(new Date()) .setNotBefore(new Date()) .setExpiresAt(new Date(System.currentTimeMillis() + 3600000)) // 1小时后过期 .setSigner(signer) .sign(); System.out.println("生成的 JWT: " + token); return token; } // 2. 验证 JWT public static boolean validateJwt(String token) { try { // 验证签名和过期时间 JWTValidator.of(token) .validateDate() // 验证时间范围(签发时间、生效时间、过期时间) .validateAlgorithm(JWTSignerUtil.hs256(SECRET.getBytes())); return true; } catch (Exception e) { System.out.println("JWT 验证失败: " + e.getMessage()); return false; } } // 3. 解析 JWT 数据 public static void parseJwt(String token) { JWT jwt = JWT.of(token); // 验证密钥 boolean isValid = jwt.setKey(SECRET.getBytes()).verify(); System.out.println("签名验证: " + isValid); if (isValid) { // 获取载荷数据 Integer uid = (Integer) jwt.getPayload("uid"); String name = (String) jwt.getPayload("name"); String email = (String) jwt.getPayload("email"); System.out.println("用户ID: " + uid); System.out.println("用户名: " + name); System.out.println("邮箱: " + email); System.out.println("签发时间: " + jwt.getPayload("iat")); System.out.println("过期时间: " + jwt.getPayload("exp")); } } public static void main(String[] args) { // 生成 token String token = createJwt(); // 验证 token System.out.println("\n验证结果: " + validateJwt(token)); // 解析 token System.out.println("\n解析结果:"); parseJwt(token); } }

4. 高级用法

4.1 自定义签名算法

// HS256(默认) JWTSigner signer = JWTSignerUtil.hs256(key.getBytes()); // HS384 JWTSigner signer = JWTSignerUtil.hs384(key.getBytes()); // HS512 JWTSigner signer = JWTSignerUtil.hs512(key.getBytes()); // 使用 RSA 算法(需要先准备好公私钥) JWTSigner signer = JWTSignerUtil.rs256(privateKey, publicKey);

4.2 刷新 Token

public class JwtRefreshUtil { private static final String SECRET = "refreshSecretKey"; // 检查是否需要刷新(例如过期前30分钟) public static boolean needRefresh(String token) { JWT jwt = JWT.of(token); Date expDate = jwt.getPayload("exp"); long remainTime = expDate.getTime() - System.currentTimeMillis(); return remainTime < 30 * 60 * 1000; // 剩余时间小于30分钟 } // 刷新 token(基于旧 token 生成新 token) public static String refreshToken(String oldToken) { JWT oldJwt = JWT.of(oldToken); // 复制原有载荷,更新过期时间 Map<String, Object> newPayload = new HashMap<>(); oldJwt.getPayloads().forEach((key, value) -> { if (!"exp".equals(key) && !"iat".equals(key)) { newPayload.put(key, value); } }); return JWT.create() .setPayload(newPayload) .setIssuedAt(new Date()) .setExpiresAt(new Date(System.currentTimeMillis() + 3600000)) .setKey(SECRET.getBytes()) .sign(); } }

4.3 Spring Boot 集成示例

// JwtUtils 工具类 @Component public class JwtUtils { @Value("${jwt.secret}") private String secret; @Value("${jwt.expire}") private Long expire; public String generateToken(String username) { Map<String, Object> claims = new HashMap<>(); claims.put("username", username); claims.put("createTime", System.currentTimeMillis()); return JWT.create() .setPayload(claims) .setExpiresAt(new Date(System.currentTimeMillis() + expire)) .setKey(secret.getBytes()) .sign(); } public String getUsernameFromToken(String token) { return (String) JWT.of(token) .setKey(secret.getBytes()) .getPayload("username"); } public boolean validateToken(String token) { try { JWT.of(token).setKey(secret.getBytes()).verify(); JWTValidator.of(token).validateDate(); return true; } catch (Exception e) { return false; } } } // 拦截器 public class JwtInterceptor implements HandlerInterceptor { @Autowired private JwtUtils jwtUtils; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); if (token != null && token.startsWith("Bearer ")) { token = token.substring(7); if (jwtUtils.validateToken(token)) { String username = jwtUtils.getUsernameFromToken(token); request.setAttribute("username", username); return true; } } response.setStatus(401); return false; } }

5. 常见问题

5.1 JWT 验证失败

// 确保密钥一致 // 检查是否过期 JWTValidator.of(token).validateDate(); // 验证算法 boolean valid = JWT.of(token) .setKey(secret.getBytes()) .verify();

5.2 中文乱码

// 设置签名器时指定字符集 JWTSigner signer = JWTSignerUtil.hs256(secret.getBytes(StandardCharsets.UTF_8));

6. 注意事项

  1. 密钥安全:密钥不要硬编码,应配置在配置文件中

  2. Token 长度:JWT 会随着载荷增大而变长,注意控制载荷大小

  3. 不要存放敏感信息:JWT 载荷是 Base64 编码,不是加密

  4. 过期时间:合理设置过期时间,不宜过长

  5. 注销问题:JWT 无法主动注销,需要配合黑名单机制

http://www.jsqmd.com/news/696306/

相关文章:

  • Python数据类型转换实现方法
  • 2026边墙风机行业深度选型对比|英飞风机、格林瀚克、依必安派特三家核心全解析
  • Cesium-Wind:3步构建专业级3D风场可视化系统
  • 机器学习模型评估的统计学方法与置信区间计算
  • AUTOSAR vs OSEK:从DBC文件里的网络管理属性,看懂两种NM协议的区别与配置
  • QtScrcpy:三分钟实现安卓设备在电脑上的零延迟投屏
  • 基于Reflexion框架的AI智能体反思机制:从错误中学习的自主调试实践
  • 为什么你的AI数据分析助手总被吐槽?#CHI2026论文解读
  • 2026Q2自贡中考低分择校:正规靠谱中职院校名录 - 优质品牌商家
  • 还在为答辩PPT熬夜?百考通AI三步搞定,让你专注内容与表达
  • 2026工业级实战:YOLO模型从200MB无损压缩到20MB,边缘部署帧率暴涨10倍全方案
  • OpenAI注册登录总报错?别慌,这份保姆级排错指南(含IP、Cloudflare、节点选择)
  • 异构计算通用SDK:跨平台高性能计算的统一编程接口
  • 2026年比较好的塑粉/耐高温塑粉/聚酯塑粉高口碑品牌推荐 - 品牌宣传支持者
  • real-anime-z惊艳生成:半透明材质(玻璃/纱质/水膜)光学特性还原
  • 云原生环境中的边缘计算:从K3s到边缘节点的全栈部署
  • Flutter跑马灯进阶玩法:除了marquee插件,试试用AnimationController和Transform手动打造丝滑滚动效果
  • FS8025BH支持PD诱骗取电快充协议芯支持 PD3.1: 5V、 9V、 12V、 15V、 20V、 28V、36V、48V
  • 智能体系统安全架构设计的五大核心范式
  • 终极Windows驱动清理指南:Driver Store Explorer完全教程
  • 2026年靠谱的四川个人住人活动板房/临时居住活动板房优质供应商推荐 - 品牌宣传支持者
  • 分布式量子计算COMPAS架构解析与优化实践
  • Qwen3-4B-Instruct实战教程:WebUI接口对接Postman+API调用示例代码
  • 从零搭建:基于ESP-01S与阿里云IoT平台,打造微信小程序远程温湿度监测与灯光控制系统
  • 还在为游戏控制设备烦恼吗?vJoy虚拟手柄让一切变得简单
  • Kali Linux下用Nmap爆破MySQL弱口令,结果全是‘No valid accounts found‘?手把手教你排查PHPStudy远程连接配置
  • 为什么92%的车载软件团队弃用Eclipse改用VSCode?——基于ISO 26262 ASIL-B项目实测的4项性能跃升数据报告
  • 告别扫描PDF的‘灰头土脸’:用ComicEnhancePro和Acrobat DC打造可搜索的清爽电子书
  • CSDN技术博文灵感生成器:用Phi-4-mini-reasoning快速构思AI与编程教程大纲
  • 空间计算AR云构建:软件测试从业者的机遇与挑战