十六、JWT令牌验证
JWT(JSON Web Token)是一种用于在网络上安全传输信息的紧凑、URL 安全的表示形式。它是一种无状态的身份验证机制,常用于现代Web应用和服务之间传递用户身份信息或授权数据。JWT 设计用于在各方之间安全地传输信息,并且信息是可以被验证和信任的。
JWT 由三个部分组成,它们通过点(.)分隔,头部(Header)、负载(Payload)、签名(Signature)。
使用场景:用户身份验证、单点登录、微服务间的通信、移动应用认证等
用户身份验证流程:用户登录、服务器验证、客户端存储JWT、请求附带JWT、服务器验证JWT。
1、具体实现
1、导入对应的jar包
<!--JWT令牌-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.5</version>
</dependency>
2、创建Jwt工具类
/**
* jwt工具类
*/
@Slf4j
public class JwtUtil {
private static final String SECRET = "yhzy"; // 密钥:可任意字符串
private static final long defaultExpire = 1000 * 60 * 60 * 24 * 7L;//过期时间:7天
//创建一个jwt密钥 加密和解密都需要用这个玩意
private static final SecretKey key = Jwts.SIG.HS256.key()
.random(new SecureRandom(SECRET.getBytes(StandardCharsets.UTF_8)))
.build();
private JwtUtil() {
}
/**
* 使用默认过期时间(7天),生成一个JWT
*
* @param claims JWT中的数据
* @return
*/
public static String createToken( Map<String, Object> claims) {
return createToken(claims, defaultExpire);
}
/**
* 生成token
*
* @param claims 请求体数据
* @param expire 过期时间 单位:毫秒
* @return token
*/
public static String createToken(Map<String, Object> claims, Long expire) {
JwtBuilder builder = Jwts.builder();
Date now = new Date();
// 生成token
builder.issuer("yhzy.fun") //签发者
.claims(claims) //数据
.issuedAt(now) //签发时间
.expiration(new Date(now.getTime() + expire)) //过期时间
.signWith(key); //签名方式
builder.header().add("JWT", "JSpWdhuPGblNZApVclmX");
return builder.compact();
}
/**
* 解析token
*
* @param token jwt token
* @return Claims
*/
public static Claims parseToken(String token) {
try {
return Jwts.parser()
.verifyWith(key) //密钥
.build()
.parseSignedClaims(token)
.getPayload();
} catch (Exception e) {
if (e instanceof ExpiredJwtException) {
// 判断JWT是否过期了 如果过期会抛出ExpiredJwtException异常
throw new JwtVerificationException("token已过期");
}
if (e instanceof JwtException) {
throw new JwtVerificationException("token已失效");
}
log.info("jwt解析失败" + e);
throw new JwtVerificationException("token解析失败");
}
}
}
3、测试:生成token 和解析 token ,也可以通过在线工具解析测试:https://tooltt.com/jwt-decode
@SpringBootTest
class ApplicationTests {
//生成token
@Test
void createJwtTest(){
//创建一个Map对象,将数据封装到Map中,并生成token
Map<String, Object> claims = Map.of("id", 1, "username", "yhzy");
//调用工具类生成token
String token=JwtUtil.createToken(claims);
System.out.println(token);
}
//解析token
@Test
void parseJwtTest(){
//解析token:将生成的Token进行解析
String token="eyJKV1QiOiJKU3BXZGh1UEdibE5aQXBWY2xtWCIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJ5aHp5LmZ1biIsImlkIjoxLCJ1c2VybmFtZSI6InloenkiLCJpYXQiOjE3Mjk2NzUxODIsImV4cCI6MTczMDI3OTk4Mn0.R828xZjAAof-KOMxppTtZkqL58TbDwgXUeG9fCTM-RA";
Claims claims = JwtUtil.parseToken(token); //解析token
System.out.println(claims);
}
}