diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java b/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java index 1a01c70..aaae16c 100644 --- a/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java +++ b/common/service-utils/src/main/java/cn/bunny/common/service/context/BaseContext.java @@ -1,10 +1,13 @@ package cn.bunny.common.service.context; +import cn.bunny.vo.system.login.LoginVo; + public class BaseContext { private static final ThreadLocal userId = new ThreadLocal<>(); private static final ThreadLocal username = new ThreadLocal(); private static final ThreadLocal adminId = new ThreadLocal<>(); private static final ThreadLocal adminName = new ThreadLocal<>(); + private static final ThreadLocal loginVo = new ThreadLocal<>(); // 用户id相关 public static Long getUserId() { @@ -23,9 +26,18 @@ public class BaseContext { username.set(_username); } + public static LoginVo getLoginVo() { + return loginVo.get(); + } + + public static void setLoginVo(LoginVo _loginVo) { + loginVo.set(_loginVo); + } + public static void removeUser() { username.remove(); userId.remove(); + loginVo.remove(); } // adminId 相关 diff --git a/common/service-utils/src/main/java/cn/bunny/common/service/utils/RequestUtil.java b/common/service-utils/src/main/java/cn/bunny/common/service/utils/RequestUtil.java new file mode 100644 index 0000000..b7942db --- /dev/null +++ b/common/service-utils/src/main/java/cn/bunny/common/service/utils/RequestUtil.java @@ -0,0 +1,57 @@ +package cn.bunny.common.service.utils; + +import cn.bunny.common.service.exception.BunnyException; +import cn.bunny.pojo.result.ResultCodeEnum; +import jakarta.servlet.http.HttpServletRequest; + +import java.net.Inet6Address; +import java.net.InetAddress; + +public class RequestUtil { + public static String getHttpIpAddress(HttpServletRequest request) { + + String ipv6Address = request.getRemoteAddr(); + try { + InetAddress inetAddress = InetAddress.getByName(ipv6Address); + if (inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress()) { + System.out.println("IPv4 Address: " + inetAddress.getHostAddress()); + } else { + InetAddress ipv4Address = Inet6Address.getByAddress(null, inetAddress.getAddress(), 0); + System.out.println("IPv4 Address: " + ipv4Address.getHostAddress()); + } + } catch (Exception e) { + throw new BunnyException(ResultCodeEnum.SERVICE_ERROR); + } + String ipAddress = request.getHeader("X-Forwarded-For"); + + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_X_FORWARDED"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_CLIENT_IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_FORWARDED_FOR"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("HTTP_FORWARDED"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("REMOTE_ADDR"); + } + + return ipAddress; + } +} diff --git a/dao/src/main/java/cn/bunny/entity/system/log/SystemLog.java b/dao/src/main/java/cn/bunny/entity/system/log/SystemLog.java index 18781db..02a0f00 100644 --- a/dao/src/main/java/cn/bunny/entity/system/log/SystemLog.java +++ b/dao/src/main/java/cn/bunny/entity/system/log/SystemLog.java @@ -61,6 +61,9 @@ public class SystemLog implements Serializable { @ApiModelProperty("当前用户token") private String token; + @ApiModelProperty("当前用户IP地址") + private String ipAddress; + @ApiModelProperty("创建时间") private LocalDateTime createTime; diff --git a/server-gateway/src/main/java/cn/bunny/service/gateway/task/TemplateTask.java b/server-gateway/src/main/java/cn/bunny/service/gateway/task/TemplateTask.java deleted file mode 100644 index d3232bd..0000000 --- a/server-gateway/src/main/java/cn/bunny/service/gateway/task/TemplateTask.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.bunny.service.gateway.task; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -@Component -@Slf4j -public class TemplateTask { - @Scheduled(cron = "0/1 5 * * * ?") - public void templateTask() { - log.info("定时任务执行..."); - } -} diff --git a/service/service-web/src/main/java/cn/bunny/service/web/aop/aspect/AutoLogAspect.java b/service/service-web/src/main/java/cn/bunny/service/web/aop/aspect/AutoLogAspect.java index 6ad8d09..d820247 100644 --- a/service/service-web/src/main/java/cn/bunny/service/web/aop/aspect/AutoLogAspect.java +++ b/service/service-web/src/main/java/cn/bunny/service/web/aop/aspect/AutoLogAspect.java @@ -54,24 +54,27 @@ public class AutoLogAspect { Map mapByToken = JwtHelper.getMapByToken(token); LoginVo loginVo = JSONObject.parseObject(JSONObject.toJSONString(mapByToken), LoginVo.class); + // 插入Ip地址 + systemLog.setIpAddress(request.getRemoteHost()); try { // 当为null时跳过执行 if (annotation != null) return joinPoint.proceed(); - - // TODO 将请求头token全部转成 map - systemLog.setClassPath(classPath); - systemLog.setMethodName(methodName); if (args.equals("[null]")) { systemLog.setArgs(null); } else { systemLog.setArgs(args); } - systemLog.setToken(token); + // 登录返回Vo不为空即插入 + if (loginVo != null) { + systemLog.setNickname(loginVo.getNickName()); + systemLog.setEmail(loginVo.getEmail()); + systemLog.setUpdateUser(loginVo.getId()); + } - systemLog.setNickname(loginVo.getNickName()); - systemLog.setEmail(loginVo.getEmail()); - systemLog.setUpdateUser(loginVo.getId()); + systemLog.setClassPath(classPath); + systemLog.setMethodName(methodName); + systemLog.setToken(token); // 目标对象(连接点)方法的执行 result = joinPoint.proceed(); diff --git a/service/service-web/src/main/java/cn/bunny/service/web/interceptor/UserTokenInterceptor.java b/service/service-web/src/main/java/cn/bunny/service/web/interceptor/UserTokenInterceptor.java index 719e924..66a3883 100644 --- a/service/service-web/src/main/java/cn/bunny/service/web/interceptor/UserTokenInterceptor.java +++ b/service/service-web/src/main/java/cn/bunny/service/web/interceptor/UserTokenInterceptor.java @@ -1,11 +1,13 @@ package cn.bunny.service.web.interceptor; -import cn.bunny.pojo.result.constant.RedisUserConstant; -import cn.bunny.pojo.result.ResultCodeEnum; -import cn.bunny.pojo.result.Result; import cn.bunny.common.service.context.BaseContext; import cn.bunny.common.service.utils.JwtHelper; import cn.bunny.common.service.utils.ResponseUtil; +import cn.bunny.pojo.result.Result; +import cn.bunny.pojo.result.ResultCodeEnum; +import cn.bunny.pojo.result.constant.RedisUserConstant; +import cn.bunny.vo.system.login.LoginVo; +import com.alibaba.fastjson2.JSONObject; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -16,6 +18,8 @@ import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; +import java.util.Map; + @Component @Slf4j public class UserTokenInterceptor implements HandlerInterceptor { @@ -23,17 +27,22 @@ public class UserTokenInterceptor implements HandlerInterceptor { private RedisTemplate redisTemplate; @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - log.info("UserTokenInterceptor===>设置拦截器"); + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("token"); - Long userId = JwtHelper.getUserId(token); - String username = JwtHelper.getUsername(token); - Object redisUserinfo = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(username)); + Map mapByToken = JwtHelper.getMapByToken(token); + LoginVo loginVo = JSONObject.parseObject(JSONObject.toJSONString(mapByToken), LoginVo.class); + Object redisUserinfo = redisTemplate.opsForValue().get(RedisUserConstant.getUserLoginInfoPrefix(loginVo.getEmail())); // 不是动态方法直接返回 if (!(handler instanceof HandlerMethod)) return true; + + // token过期-提示身份验证过期 + if (JwtHelper.isExpired(token)) { + ResponseUtil.out(response, Result.error(ResultCodeEnum.AUTHENTICATION_EXPIRED)); + return false; + } // 解析不到userId - if (userId == null) { + if (loginVo.getId() == null) { ResponseUtil.out(response, Result.error(ResultCodeEnum.LOGIN_AUTH)); return false; } @@ -42,8 +51,9 @@ public class UserTokenInterceptor implements HandlerInterceptor { return false; } - BaseContext.setUserId(userId); - BaseContext.setUsername(username); + BaseContext.setUserId(loginVo.getId()); + BaseContext.setUsername(loginVo.getEmail()); + BaseContext.setLoginVo(loginVo); return true; } diff --git a/service/service-web/src/test/java/cn/bunny/jwt/JwtHelperTest.java b/service/service-web/src/test/java/cn/bunny/jwt/JwtHelperTest.java index edaf1f1..ef4af91 100644 --- a/service/service-web/src/test/java/cn/bunny/jwt/JwtHelperTest.java +++ b/service/service-web/src/test/java/cn/bunny/jwt/JwtHelperTest.java @@ -99,7 +99,7 @@ class JwtHelperTest { createTokenWithMapToken = "eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_23MTQ6CMBBA4buMW_oz7VChK0_gHcZSQpUiwWpMCHe3B3D9vbwdVt44g9-PBpYUHlfOETy8X3G7xC_ndY4yPDM0wB8uvFWbSlm9Umh6aRClRdl2nrTW6qTCxKW2aQCPxjYQM6f5_-9eUgXqWzThRmKk8SzIaBSMzgnXsuuI-sFqguMH0SvcYacAAAA.qW_gqkc8RQJM-UbFVj7xldSEv1RORO4qlw6VMrTEmM0"; createTokenWithMapToken = "eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_23MSw7CIBRA0b08p_yhFBi5AvfwApiiRQmiMWm6d7sAx-fmbtCwY4Ww7QQeJd4vWDMEeL9yP-cv1rZmFp8VCOAHB_bDljFa4Fwqz5SUTEs2uWCEEPzE44LjaEuCIJUmkCuW9f_vNsoBaJ1yYnZ0Rqep8VlRnESi3khrklFeXC3sP3hOgQ2nAAAA.bkPBbfpLd21eaJE2gjzniUx5n9VvCqWSY_zBiu8oO9k"; - Map tokenByMap = JwtHelper.getTokenByMap(createTokenWithMapToken); + Map tokenByMap = JwtHelper.getMapByToken(createTokenWithMapToken); // 转为Java实体对戏那个 User user = JSONObject.parseObject(JSONObject.toJSONString(tokenByMap), User.class); @@ -114,7 +114,7 @@ class JwtHelperTest { createTokenWithMapToken = "eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_23MTQ7CIBBA4buMW36nQAsrT-AdpoApWrSpaEya3t0ewPX38jZYaKUKYdsZPEq8X6hmCPB-5fWcv1SXOYv4rMCAPtRoPWxqbQlSavQCtRadFnYIRiklTzJO1I62JAgaOwa5Upn__26tHIBjTOSvxB2agRurDCeTHMceE1nne6dH2H-VOEqApwAAAA.j5BcFLT-2HENeYS8LvD27tyRnI1rE-iFzjBy1iY02T4"; createTokenWithMapToken = "eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_23MTQ7CIBBA4buM2_JXWkpZeQLvMNIhRYsSRGPS9O5yANffy9shY8EEbj86eER_v2AicPB-UTnTF1PeiPtngg7wgxVLs7XW7IRQ_cx7pbhWfLRukFKKk_Ar1tbGBZzqdQeUMG7_f7caG1zlZCZDyGavFzZ4MzC0ZmIWQ1DWeBtGguMHw7854qcAAAA.V4VLIJ7vUqnfd1LeQkXa3t8V_376DWVAA_g0PE_6_S8"; - Map tokenByMap = JwtHelper.getTokenByMap(createTokenWithMapToken, key); + Map tokenByMap = JwtHelper.getMapByToken(createTokenWithMapToken, key); // 转为Java实体对戏那个 User user = JSONObject.parseObject(JSONObject.toJSONString(tokenByMap), User.class); System.out.println(user);