diff --git a/dq-financial-hrms-auth/pom.xml b/dq-financial-hrms-auth/pom.xml index 51f3e298..c993f85e 100644 --- a/dq-financial-hrms-auth/pom.xml +++ b/dq-financial-hrms-auth/pom.xml @@ -25,43 +25,32 @@ dq-framework-common 1.0-SNAPSHOT --> + + com.auth0 + java-jwt + 3.2.0 + + + io.jsonwebtoken + jjwt + 0.7.0 + com.daqing.framework dq-framework-model 1.0-SNAPSHOT - - org.springframework.boot - spring-boot-starter-data-redis - - - + org.springframework.cloud spring-cloud-starter-openfeign - - + @@ -51,17 +40,24 @@ mybatis-plus-generator 3.0.7.1 - + org.projectlombok lombok 1.18.12 + + commons-lang + commons-lang + 2.6 + + + org.apache.commons + commons-lang3 + 3.8.1 + + io.springfox @@ -75,16 +71,14 @@ - org.springframework.boot - spring-boot-starter-web - 2.1.8.RELEASE - + com.auth0 + java-jwt + 3.2.0 + + + io.jsonwebtoken + jjwt + 0.7.0 @@ -99,6 +93,7 @@ 5.2.8.RELEASE + com.google.guava guava diff --git a/dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/SpringContextHolder.java b/dq-framework-common/src/main/java/com/daqing/framework/SpringContextHolder.java similarity index 97% rename from dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/SpringContextHolder.java rename to dq-framework-common/src/main/java/com/daqing/framework/SpringContextHolder.java index 77a606a0..fdbd0e29 100644 --- a/dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/SpringContextHolder.java +++ b/dq-framework-common/src/main/java/com/daqing/framework/SpringContextHolder.java @@ -1,4 +1,4 @@ -package com.daqing.financial.hrauth; +package com.daqing.framework; import org.springframework.beans.factory.DisposableBean; import org.springframework.context.ApplicationContext; diff --git a/dq-framework-common/src/main/java/com/daqing/framework/util/JwtUtils.java b/dq-framework-common/src/main/java/com/daqing/framework/util/JwtUtils.java new file mode 100644 index 00000000..e6eeda6f --- /dev/null +++ b/dq-framework-common/src/main/java/com/daqing/framework/util/JwtUtils.java @@ -0,0 +1,97 @@ +package com.daqing.framework.util; + + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.bouncycastle.util.encoders.Base64; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.security.SignatureException; +import java.util.Date; + +public class JwtUtils { + /** + * 签发JWT + * + * @param id + * @param subject 可以是JSON数据 尽可能少 + * @param ttlMillis + * @return String + * + */ + public static String createJWT(Long id, String subject, long ttlMillis) { + SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; + long nowMillis = System.currentTimeMillis(); + Date now = new Date(nowMillis); + SecretKey secretKey = generalKey(); + JwtBuilder builder = Jwts.builder().setId(String.valueOf(id)).setSubject(subject) // 主题 + .setIssuer("user") // 签发者 + .setIssuedAt(now) // 签发时间 + .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙 + if (ttlMillis >= 0) { + long expMillis = nowMillis + ttlMillis; + Date expDate = new Date(expMillis); + builder.setExpiration(expDate); // 过期时间 + } + return builder.compact(); + } + + public static void main(String[] args) { + //System.out.printf(createJWT("1","111", 10000000)); + boolean isTrue = validateJWT("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoiMTExIiwiaXNzIjoidXNlciIsImlhdCI6MTYwMTM0MzYyNywiZXhwIjoxNjAxMzUzNjI3fQ.q5Ssg2LM1OzzgvVWqLhgP_Hko0-pfeNO5bvpUE5KQ-s"); + System.out.println(isTrue); + } + + /** + * 验证JWT + * + * @param jwtStr + * @return + */ + public static Boolean validateJWT(String jwtStr) { + //boolean isValidate = false; + Claims claims = null; + try { + claims = parseJWT(jwtStr); + return true; + } catch (ExpiredJwtException e) { + return false; + } catch (SignatureException e) { + return false; + } catch (Exception e) { + return false; + } + //return checkResult; + } + + public static SecretKey generalKey() { + byte[] encodedKey = Base64.decode("JWTDQ123456"); + SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES"); + return key; + } + + /** + * + * 解析JWT字符串 + * + * @param jwt + * @return + * @throws Exception + */ + public static Claims parseJWT(String jwt) throws Exception { + SecretKey secretKey = generalKey(); + return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody(); + } + + public static void putTokenToRedis(Long userId, String token, long times) { + RedisUtil.setEx("dq:token:"+token, String.valueOf(userId), times); + } + + public static void removeTokenByToken(String token) { + RedisUtil.del("dq:token:"+token); + } +} \ No newline at end of file diff --git a/dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/util/RedisUtil.java b/dq-framework-common/src/main/java/com/daqing/framework/util/RedisUtil.java similarity index 95% rename from dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/util/RedisUtil.java rename to dq-framework-common/src/main/java/com/daqing/framework/util/RedisUtil.java index de1bf1a8..0da8d44e 100644 --- a/dq-financial-hrms-auth/src/main/java/com/daqing/financial/hrauth/util/RedisUtil.java +++ b/dq-framework-common/src/main/java/com/daqing/framework/util/RedisUtil.java @@ -1,7 +1,7 @@ -package com.daqing.financial.hrauth.util; +package com.daqing.framework.util; -import com.daqing.financial.hrauth.SpringContextHolder; +import com.daqing.framework.SpringContextHolder; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.StringRedisTemplate; @@ -19,6 +19,13 @@ public class RedisUtil { private final static StringRedisTemplate stringRedisTemplate = SpringContextHolder.getBean("stringRedisTemplate"); + /*static private RedisTemplate stringRedisTemplate; + static private RedisTemplate getRedisTemplate() { + if (stringRedisTemplate == null) { + stringRedisTemplate = SpringContextHolder.getBean("redisTemplate"); + } + return stringRedisTemplate; + }*/ /** * 匹配key */ diff --git a/dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/LoginLog.java b/dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/LoginLog.java new file mode 100644 index 00000000..776335b5 --- /dev/null +++ b/dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/LoginLog.java @@ -0,0 +1,28 @@ +package com.daqing.framework.domain.hrms; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("hrms_login_log") +public class LoginLog { + + @TableId(type = IdType.AUTO) + private int id; + + //用户id + private Long userId; + + //登录次数 + private int loginNum; + + //创建时间 + private Date createTime; + + //最新登录时间 + private Date newestTime; +} diff --git a/dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/Token.java b/dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/Token.java new file mode 100644 index 00000000..9a5713fb --- /dev/null +++ b/dq-framework-model/src/main/java/com/daqing/framework/domain/hrms/Token.java @@ -0,0 +1,18 @@ +package com.daqing.framework.domain.hrms; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("hrms_token") +public class Token { + + @TableId(type = IdType.INPUT) + private Long userId; + private String token; + private Date createTime; +} diff --git a/dq-framework-utils/pom.xml b/dq-framework-utils/pom.xml index 1f394dfc..3eb91834 100644 --- a/dq-framework-utils/pom.xml +++ b/dq-framework-utils/pom.xml @@ -25,18 +25,6 @@ - @@ -44,6 +32,11 @@ dq-framework-common 1.0-SNAPSHOT + + org.springframework.boot + spring-boot-starter-web + 2.1.8.RELEASE + com.aliyun.oss aliyun-sdk-oss @@ -66,17 +59,5 @@ 5.1.9.RELEASE compile - \ No newline at end of file diff --git a/dq-govern-gateway/pom.xml b/dq-govern-gateway/pom.xml index 1cbbb367..4218219e 100644 --- a/dq-govern-gateway/pom.xml +++ b/dq-govern-gateway/pom.xml @@ -21,11 +21,16 @@ + + com.daqing.framework + dq-framework-common + 1.0-SNAPSHOT + org.springframework.cloud spring-cloud-starter-gateway - + - + + diff --git a/dq-govern-gateway/src/main/java/com/daqing/financial/gateway/config/ApiGlobalFilter.java b/dq-govern-gateway/src/main/java/com/daqing/financial/gateway/config/ApiGlobalFilter.java index 53ad45d0..1c03c1da 100644 --- a/dq-govern-gateway/src/main/java/com/daqing/financial/gateway/config/ApiGlobalFilter.java +++ b/dq-govern-gateway/src/main/java/com/daqing/financial/gateway/config/ApiGlobalFilter.java @@ -1,7 +1,8 @@ package com.daqing.financial.gateway.config; import com.alibaba.fastjson.JSONObject; -import com.daqing.financial.gateway.util.RedisUtil; +import com.daqing.framework.util.JwtUtils; +import com.daqing.framework.util.RedisUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.gateway.filter.GatewayFilterChain; @@ -57,9 +58,9 @@ public class ApiGlobalFilter implements GlobalFilter, Ordered { //有数据 }else { //校验token - //Long userId = verifyJWT(token); - String userId = RedisUtil.get("dq:token:"+token); - if (userId == null || "".equals(userId)){ + boolean isVerify = verifyJWT(token); + //String userId = RedisUtil.get("dq:token:"+token); + if (! isVerify){ JSONObject message = new JSONObject(); message.put("message", "登录已失效,请重新登录"); message.put("code", "401"); @@ -70,7 +71,7 @@ public class ApiGlobalFilter implements GlobalFilter, Ordered { return response.writeWith(Mono.just(buffer)); } //将现在的request,添加当前身份 - ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization-UserId", userId).build(); + ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization", token).build(); ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build(); return chain.filter(mutableExchange); } @@ -83,9 +84,13 @@ public class ApiGlobalFilter implements GlobalFilter, Ordered { * @param token * @return userPhone */ - private Long verifyJWT(String token){ + private Boolean verifyJWT(String token){ String id = RedisUtil.get("dq:token:"+token); - return Long.parseLong(id); + if(id == null || "".equals(id)){ + return false; + } + return JwtUtils.validateJWT(token); + //return Long.parseLong(id); } @Override