JWT工具类
typescript
复制代码
mport io.jsonwebtoken.*;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;
public class JWTUtils {
// TOKEN的有效期一个小时(S)
private static final int TOKEN_TIME_OUT = 3_600 ;
// 加密KEY
private static final String TOKEN_ENCRY_KEY = "ABCD";
// 最小刷新间隔(S)
private static final int REFRESH_TIME = 300;
// 生产ID
public static String getToken(Long id){
Map<String, Object> claimMaps = new HashMap<>();
claimMaps.put("id",id);
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString())
.setIssuedAt(new Date(currentTime)) //签发时间
.setSubject("description") //说明
.setIssuer("xyy") //签发者信息
.setAudience("admin") //接收用户
.compressWith(CompressionCodecs.GZIP) //数据压缩方式
.signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
.setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
.addClaims(claimMaps) //cla信息
.compact();
}
/**
* 获取token中的claims信息
*
* @param token
* @return
*/
private static Jws<Claims> getJws(String token) {
return Jwts.parser()
.setSigningKey(generalKey())
.parseClaimsJws(token);
}
/**
* 获取payload body信息
*
* @param token
* @return
*/
public static Claims getClaimsBody(String token) {
try {
return getJws(token).getBody();
}catch (ExpiredJwtException e){
return null;
}
}
/**
* 获取hearder body信息
*
* @param token
* @return
*/
public static JwsHeader getHeaderBody(String token) {
return getJws(token).getHeader();
}
/**
* 是否过期
*
* @param claims
* @return -1:有效,0:有效,1:过期,2:过期
*/
public static int verifyToken(Claims claims) {
if(claims==null){
return 1;
}
try {
claims.getExpiration()
.before(new Date());
// 需要自动刷新TOKEN
if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
return -1;
}else {
return 0;
}
} catch (ExpiredJwtException ex) {
return 1;
}catch (Exception e){
return 2;
}
}
/**
* 由字符串生成加密key
*
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
内容打印
csharp
复制代码
public class ResultTest {
public static void main(String[] args) {
// eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQrDIBBF7zLrCA6a0eQ2xlGYQttQDSSE3r3jorvHf__d8OgCK6DlmX1lUzAvxlc_m2jrYjJFQhdwI_QwgaQOK1IMZF2IdoJ2bFpzafkje5f3a5xa0-28LuV0sHLipwxTzv2fBzdyUYvfH4GZVoyFAAAA.5dtA7NVIyITnHKjYidIej9v2o9wdxkhrqH_lXqTbRgJVQ-h3hC7QPhzWnMeABxgUadedJyjaPcYSiE7Yr63oEw
String token = JWTUtils.getToken(1L);
// 根据id生成token
System.out.println("根据id生成token为"+token);
JwsHeader header = JWTUtils.getHeaderBody(token);
// 输出头部信息
System.out.println("头部信息"+header);
Claims body = JWTUtils.getClaimsBody(token);
// 输出详情信息
System.out.println("详情信息"+body);
String exp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(body.getExpiration());
// 输出Body的过期时间
System.out.println("过期时间"+exp);
int result = JWTUtils.verifyToken(body);
// 根据body校验是否过期
System.out.println("token状态为"+result);
}
}
ini
复制代码
根据id生成token为eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQrDIBBF7zLrCI4mo8ltjGZgCm1DNZAQeveOi-4e__13w6MJLMDWBsduNhZzNuM8oUmeyfiS2TGuGCeEASQ1WJBiIDsGogHqsWpdtpo_sjd5v_qpVt3O61JOR1FO5SndbOf-z6PvuajF7w8AVTI8hQAAAA.Tkj3Dtn6Y9FhxohvQSmEU5Ze4AGaiI5NhEC2J4uDC_U3Ke6ePiOjNnWgW99jnljoOBqGh4RcbO4SZjR3lwd55w
头部信息{alg=HS512, zip=GZIP}
详情信息{jti=f0072f29-01cc-4951-a3f6-3dcf2f1b1851, iat=1687604766, sub=description, iss=xyy, aud=admin, exp=1687608366, id=1}
过期时间2023-06-24 20:06:06
token状态为-1
案例
用户登录
less
复制代码
@Transactional
@Slf4j
@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {
@Override
public ResponseResult login(LoginDto dto) {
// 正式登录,用户名和密码
if(StringUtils.isNotBlank(dto.getPhone())&&StringUtils.isNotBlank(dto.getPassword())){
//手机号 - > 用户信息
ApUser apUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));
if(apUser == null){
return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"用户信息不存在");
}
// 比对密码
String salt = apUser.getSalt();
String password = dto.getPassword();
String pwd = DigestUtils.md5DigestAsHex((password + salt).getBytes());
if(!pwd.equals(apUser.getPassword())){
return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);
}
// 返回数据 jwt
String token = AppJwtUtil.getToken(Long.valueOf(apUser.getId()));
Map<String,Object> map = new HashMap<>();
map.put("token",token);
apUser.setSalt("");
apUser.setPassword("");
map.put("user",apUser);
return ResponseResult.okResult(map);
}else {
// 游客登录
HashMap<String, Object> map = new HashMap<>();
map.put("token",AppJwtUtil.getToken(0L));
return ResponseResult.okResult(map);
}
}
}
网关校验
scss
复制代码
@Slf4j
@Component
public class AuthorizeFilter implements Ordered, GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取request和response
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
// 判断是否是登录
if(request.getURI().getPath().contains("/login")){
//放行
return chain.filter(exchange);
}
// 获取token
String token = request.getHeaders().getFirst("token");
// 判断token是否存在
if(StringUtils.isBlank(token)){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
// 判断token是否有效
try{
Claims claimsBody = AppJwtUtil.getClaimsBody(token);
//是否是过期
int result = AppJwtUtil.verifyToken(claimsBody);
if(result==1||result==2){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
}catch(Exception e){
e.printStackTrace();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
//放行
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}