package com.ils.oms.utils; import cn.hutool.core.date.DateUtil; import cn.hutool.core.exceptions.ValidateException; import cn.hutool.core.lang.TypeReference; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.hutool.jwt.JWT; import cn.hutool.jwt.JWTPayload; import cn.hutool.jwt.RegisteredPayload; import cn.hutool.jwt.signers.JWTSigner; import cn.hutool.jwt.signers.JWTSignerUtil; import com.ils.oms.result.JwtVerifyResult; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Date; import java.util.HashMap; import java.util.Map; @Slf4j @Component public class JwtUtil { private static final JWTSigner jwtSigner = JWTSignerUtil.hs256("!34ADAS3ddfdssdfhii@#$$@#efh3".getBytes()); private static final String AUTH_TOKEN_KEY = "ils"; private static final String APP_KEY = "ilsTestKey2023"; private static final String APP_SECRET = "ilsTestKey2023"; public static void main(String[] args) { Map payload = new HashMap<>(); payload.put("userName","ilsadmin"); payload.put("passWord", "123456"); String token = createToken(payload); log.info("token: {}",token ); JwtVerifyResult jwtVerifyResult = validateToken(token); if(jwtVerifyResult.getSuccess()){ payload = jwtVerifyResult.getPayload(); log.info("userName: {}, passWord: {}", payload.get("userName"), payload.get("passWord")); }else{ log.error("验证失败:"+jwtVerifyResult.toString()); } } /** * 生成安全的 jwt token * @param payload jwt负载 * @return */ public static String createToken(Map payload) { Date dateNow = new Date(); String authToken = SecureUtil.md5(SecureUtil.sha256(APP_KEY + "_" + DateUtil.formatDateTime(dateNow) + "_" + APP_SECRET)); payload.put(AUTH_TOKEN_KEY, authToken); return JWT.create() .addPayloads(payload) .setIssuedAt(dateNow) .setExpiresAt(DateUtil.endOfDay(dateNow)) .sign(jwtSigner); } /** * jwt 验证,1)hash256签名,2)失效时间,3)自定义二重安全校验 * @param token 生成的jwt token * @return map :当error = "ok",会额外多出 payload */ public static JwtVerifyResult validateToken(String token) { try { JWT jwt = JWT.of(token); jwt.setSigner(jwtSigner); //1.验证hash256签名 Boolean hs256Bool = jwt.verify(); if (!hs256Bool) { return new JwtVerifyResult(false, "hash256签名校验失败"); } //2.验证签名的时间,单位s Boolean validateBool = jwt.validate(60*60*24); if (!validateBool) { return new JwtVerifyResult(false, "时间负载校验失败"); } //3.获取二重 authToken 认证校验 JWTPayload jwtPayload = jwt.getPayload(); Date subAtDate = jwtPayload.getClaimsJson().getDate(RegisteredPayload.ISSUED_AT); String atScource = String.valueOf(jwtPayload.getClaim(AUTH_TOKEN_KEY)); String authToken = SecureUtil.md5(SecureUtil.sha256(APP_KEY + "_" +DateUtil.formatDateTime(subAtDate) + "_" + APP_SECRET)); if (StrUtil.isEmpty(atScource) || !atScource.equals(authToken)) { return new JwtVerifyResult(false, "二重身份认证校验失败"); } //4.将负载参数转换成map返回 JSONObject payloadJson = jwtPayload.getClaimsJson(); payloadJson.remove(AUTH_TOKEN_KEY); JwtVerifyResult jwtVerifyResult = new JwtVerifyResult(true, "签名有效"); jwtVerifyResult.setPayload(JSONUtil.toBean(payloadJson, new TypeReference>() { }, true)); return jwtVerifyResult; } catch (ValidateException e) { return new JwtVerifyResult(true, "无效的签名"); } } }