JWT简介
JWT定义 JWT全称为Json web token,也就是 Json 格式的 web token
JWT数据结构
1.JWT由三段字符串组成,中间用.分隔
Project_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNzE2MzcwMTM0LCJpYXQiOjE3MTU3NjUzMzQsImp0aSI6IjllOTljMmUzOWZlMjQzZmE4ZjdhMjkzNmMxYjMwNmQ4In0.qTy7NFaaNkpzNnvAYpu6HZl_4TmjT1mNWuyCPEtUurQ
2.JWT 的三个部分依次如下:
Header(头部)// Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。
Payload(负载)// Payload 部分是一个 JSON 对象,用来存放实际需要传递的数据
Signature(签名)// Signature 部分是对前两部分的签名,防止数据篡改
3.第一段字符Header,Base64解码后得到jwt的算法
{
"typ": "JWT", // TOKEN TYPE ,token类型
"alg": "HS256" //ALGORITHM,算法 哈希256
}
4.第二段字符Payload,解析可得到我们自定义填充的一些数据信息
PAYLOAD是数据载体,可以有自定义数据
{
"userId": "123456" // 自定义数据
}
5.第三段字符Signature
Signature 部分是对前两部分的签名,防止数据篡改。
具体实现方法:
- 导入jar
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.16</version>
</dependency>
- 封装工具类
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class JwtTokenUtil {
//过期时间
public static final Long EXPIRATION = 604800l;
// 密钥 设置的越复杂越好
public static final String SECRET = "ec15df77f55d819a3876f6543f7d89";
//token前缀
public static final String PREFIX = "Project_";
public JwtTokenUtil() {
}
public static void main(String[] args) {
System.out.println(generateToken("1"));
}
public static String generateToken(String userId) {
return PREFIX + JWT.create().withSubject(userId).withIssuedAt(new Date()).withJWTId(UUID.fastUUID().toString(true)).withExpiresAt(generateExpirationDate()).sign(Algorithm.HMAC256(SECRET));
}
public static Date generateExpirationDate() {
return new Date(System.currentTimeMillis() + (long)(EXPIRATION * 1000));
}
public boolean isTokenExpired(Date expiresAt) {
return expiresAt.before(DateUtil.date());
}
public DecodedJWT decode(String token) {
try {
return JWT.decode(this.subStrToken(token));
} catch (JWTDecodeException var3) {
throw new BadCredentialsException("token 解析出错", var3);
}
}
public String getUserIdFromSubject(String subject) {
try {
if (StrUtil.isEmpty(subject)) {
throw new UsernameNotFoundException("从token中无法解析出用户ID");
} else {
String[] subjects = subject.split("#,#");
String userName;
if (ArrayUtil.isNotEmpty(subjects)) {
userName = subjects[0];
} else {
userName = subject;
}
return userName;
}
} catch (Exception var4) {
throw new BadCredentialsException("从token中解析用户ID出错", var4);
}
}
public void verify(String token, String userId) {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm).withSubject(userId).build();
verifier.verify(this.subStrToken(token));
}
private String subStrToken(String token) {
if (token.startsWith(PREFIX)) {
token = token.substring(PREFIX.length());
}
return token;
}
}
- 测试