|  |  |  |  | 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<String,String> 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<String, String> 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<Map<String, String>>() { | 
					
						
							|  |  |  |  |             }, true)); | 
					
						
							|  |  |  |  |             return jwtVerifyResult; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         } catch (ValidateException e) { | 
					
						
							|  |  |  |  |             return new JwtVerifyResult(true, "无效的签名"); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } |