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;}
}
- 测试