JWT基本概念
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全传输信息作为JSON对象。通俗理解为:`带有防伪水印的临时身份证
它由三部分组成:
(Signature=【A:Header(经过如 Base64 编码的头)+ B:Payload(经过如 Base64 编码的内容,比如 userId=1)+ C:Secret(服务器私钥,这是唯一保密的东西)】用哈希算法生成的东西)
典型JWT格式:xxxxx.yyyyy.zzzzz eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxMjMsInVzZXJuYW1lIjoiZXhhbXBsZV91c2VyIiwiZXhwIjoxNjMwNjQ5NjAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT的实现
1. 核心依赖
首先,这个工具类是基于 Java 社区最常用的 JWT 库 jjwt 实现的。在你的 pom.xml 里加上这个依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2. 拒绝硬编码:配置文件
我们利用 Spring 的 @Value 注解,把配置参数提取到 application.yml中。这样做的好处是,将来你要修改过期时间或者更换密钥,重启一下服务就行,不用重新编译代码。
jwt:
# 密钥 (Secret):
# 建议设长一点,复杂一点,防止被暴力破解。
secret: asdfghhjttjtjtjt1111
# 过期时间 (Expiration):
# 单位是秒。 (60*60*24*7 = 604800)
expiration: 604800
3. 工具类源码深度解析
下面是完整的 JwtUtil 代码。详细解析都在代码注释中。
package com.example.demo.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component // 1. 交给 Spring 管理,方便在 Service 或 Controller 里注入
public class JwtUtil {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
/**
* 【造证】生成 JWT 令牌
*/
public String generateToken(Long userId) {
// 2. 准备载荷 (Payload)
// 我们只放 userId,因为 payload 只是 Base64 编码,不要放密码等敏感信息!
Map<String, Object> claims = new HashMap<>();
claims.put("userId", userId);
return Jwts.builder()//把数据变成一串加密字符串
.setClaims(claims) // 设置自定义数据(如userId)
.setIssuedAt(new Date()) // 设置“发证日期”为当前时间(iat)都放到claims里面了
// 3. 设置过期时间(exp)
// System.currentTimeMillis() 获取当前毫秒数
// expiration * 1000 将配置的秒转为毫秒
.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
// 4. 签名 (盖章)
// 使用 HS512 这种高强度哈希算法,配合我们的 secret 密钥进行签名
.signWith(SignatureAlgorithm.HS512, secret)
.compact(); // 压缩生成最终的 String
}
/**
* 【读证】从 token 中获取用户ID
*/
public Long getUserIdFromToken(String token) {
try {
// 5. 解析 Token
Claims claims = Jwts.parser()//把那串字符串变回原始数据(Claims)。
.setSigningKey(secret) // 本身不判断,只是收集secret(把子弹上膛)。
.parseClaimsJws(token)//拆解 Header,Payload然后和secret一起运算看看能否与token一致
.getBody();
// 拿到数据后转回 Long 类型
return Long.valueOf(claims.get("userId").toString());
} catch (Exception e) {
// 如果解析过程报错(比如 Token 被篡改、格式不对),返回 null
return null;
}
}
/**
* 【验理】验证 token 是否有效
*/
public boolean validateToken(String token) {
try {
// 6. 核心验证逻辑
// parseClaimsJws 方法非常严格,它会自动校验:
// A. 签名是否匹配 (防止篡改)
// B. 是否已过期 (ExpiredJwtException)
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (Exception e) {
// 只要有异常,统统视为验证失败
return false;
}
}
/**
* 【续期】刷新 JWT 令牌
* 简单实现:直接签发一个新的
*/
public String refreshToken(Long userId) {
return generateToken(userId);
}
}
4怎么用?(实战场景)
登录接口
用户登录成功后,你不需要像以前那样存 Session,直接发证:
@Autowired
private JwtUtil jwtUtil;
public Result login(LoginDTO loginDTO) {
User user = userService.checkLogin(loginDTO);
String token = jwtUtil.generateToken(user.getId());
return Result.ok(token);
}
码字不易,如果觉得这篇文对你有帮助的话,请点赞,评论,收藏,欢迎在评论区留言,每一条我都会看!






