JWT 实现
-
导入依赖
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.18.2</version> </dependency>
-
创建令牌
public static String secretKey = "!QAZ@123#asd.$"; @Test public void JWTCreatTest(){ Map<String, Object> map = new HashMap<>(); Calendar instance = Calendar.getInstance(); //7天后过期 instance.add(Calendar.DATE,7); String token = JWT.create().withHeader(map) .withClaim("userId",1) .withClaim("userName","WuYufan") .withExpiresAt(instance.getTime()) .sign(Algorithm.HMAC256(secretKey)); System.out.println(token); }
生成的令牌:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Ild1WXVmYW4iLCJleHAiOjE2MzI3MTk3MTYsInVzZXJJZCI6MX0.uFkoaDEIqOtHj6P8IFosE809fu4V5PgG2ezSczc9mlY
withHeader
:添加标头(Header)withClaim
:添加有效载荷(Payload)withExpiresAt
:设置过期时间sign
:添加签名(Signature) ;Algorithm.HMAC256
为加密算法 -
根据令牌和签名解析数据
@Test public void getInfoByToken(){ //创建验证对象 JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secretKey)).build(); //验证对象根据 token 获取DecodedJWT对象,该对象可以读取token中的数据 DecodedJWT verify = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Ild1WXVmYW4iLCJleHAiOjE2MzI3MTk3MTYsInVzZXJJZCI6MX0.uFkoaDEIqOtHj6P8IFosE809fu4V5PgG2ezSczc9mlY"); Integer userId = verify.getClaim("userId").asInt(); String userName = verify.getClaim("userName").asString(); //过期时间 Date expirationTime = verify.getExpiresAt(); System.out.println("userId = " + userId); System.out.println("userName = " + userName); System.out.println("expirationTime = " + expirationTime); }
运行结果:
userId = 1 userName = WuYufan expirationTime = Mon Sep 27 13:15:16 CST 2021
常见异常:
- SignatureverificationException : 签名不一致异常
- TokenExpiredException: 令牌过期异常
- AlgorithmNismatchException: 算法不匹配异常
- InvalidClaimException : 失效的payload异常
编写 JWT 工具类
package cn.edu.hziee.boot.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.Map;
public class JWTUtils {
// 密钥
private static final String SECRETKEY = "!QAzxZ@12^3#asd.$01.0..";
/**
* 获取令牌
* @param map 填入的用户信息
* @return token 生成的令牌
*/
public static String getToken(Map<String, Object> map){
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DATE,7);
//创建 JWT builder
JWTCreator.Builder builder = JWT.create();
map.forEach((k,v)->{
builder.withClaim(k,v);
});
String token = builder.withExpiresAt(instance.getTime())
.sign(Algorithm.HMAC256(SECRETKEY));
return token;
}
/**
* 验证 token 的合法性,并返回其信息
* @param token 需要验证的 token
* @return 返回 token 信息(DecodedJWT 对象)
*/
public static DecodedJWT verify(String token){
return JWT.require(Algorithm.HMAC256(SECRETKEY)).build().verify(token);
}
}