diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java b/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java index 6c189376..c6f1d958 100644 --- a/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java +++ b/eladmin-common/src/main/java/me/zhengjie/utils/StringUtils.java @@ -133,13 +133,13 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { */ public static String getIp(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); - if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } - if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } - if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } String comma = ","; @@ -169,6 +169,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { return null; } + /** + * 获取浏览器 + */ public static String getBrowser(HttpServletRequest request) { UserAgent ua = UserAgentUtil.parse(request.getHeader("User-Agent")); String browser = ua.getBrowser().toString() + " " + ua.getVersion(); diff --git a/eladmin-logging/src/main/java/me/zhengjie/aspect/LogAspect.java b/eladmin-logging/src/main/java/me/zhengjie/aspect/LogAspect.java index b5f35fdc..b091d7ba 100644 --- a/eladmin-logging/src/main/java/me/zhengjie/aspect/LogAspect.java +++ b/eladmin-logging/src/main/java/me/zhengjie/aspect/LogAspect.java @@ -88,6 +88,10 @@ public class LogAspect { sysLogService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint)joinPoint, sysLog); } + /** + * 获取用户名 + * @return / + */ public String getUsername() { try { return SecurityUtils.getCurrentUsername(); diff --git a/eladmin-logging/src/main/java/me/zhengjie/service/impl/SysLogServiceImpl.java b/eladmin-logging/src/main/java/me/zhengjie/service/impl/SysLogServiceImpl.java index 866c6339..74598b8d 100644 --- a/eladmin-logging/src/main/java/me/zhengjie/service/impl/SysLogServiceImpl.java +++ b/eladmin-logging/src/main/java/me/zhengjie/service/impl/SysLogServiceImpl.java @@ -35,8 +35,8 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Method; @@ -50,9 +50,12 @@ import java.util.*; @Service @RequiredArgsConstructor public class SysLogServiceImpl implements SysLogService { + private final LogRepository logRepository; private final LogErrorMapper logErrorMapper; private final LogSmallMapper logSmallMapper; + // 定义敏感字段常量数组 + private static final String[] SENSITIVE_KEYS = {"password"}; @Override public Object queryAll(SysLogQueryCriteria criteria, Pageable pageable) { @@ -81,6 +84,8 @@ public class SysLogServiceImpl implements SysLogService { if (sysLog == null) { throw new IllegalArgumentException("Log 不能为 null!"); } + + // 获取方法签名 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class); @@ -88,56 +93,64 @@ public class SysLogServiceImpl implements SysLogService { // 方法路径 String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()"; - // 描述 - sysLog.setDescription(aopLog.value()); - + // 获取参数 + JSONObject params = getParameter(method, joinPoint.getArgs()); + + // 填充基本信息 sysLog.setRequestIp(ip); sysLog.setAddress(StringUtils.getCityInfo(sysLog.getRequestIp())); sysLog.setMethod(methodName); sysLog.setUsername(username); - sysLog.setParams(getParameter(method, joinPoint.getArgs())); - // 记录登录用户,隐藏密码信息 - if(signature.getName().equals("login") && StringUtils.isNotEmpty(sysLog.getParams())){ - JSONObject obj = JSON.parseObject(sysLog.getParams()); - sysLog.setUsername(obj.getString("username")); - sysLog.setParams(JSON.toJSONString(Dict.create().set("username", sysLog.getUsername()))); - } + sysLog.setParams(JSON.toJSONString(params)); sysLog.setBrowser(browser); + sysLog.setDescription(aopLog.value()); + + // 如果没有获取到用户名,尝试从参数中获取 + if(StringUtils.isBlank(sysLog.getUsername())){ + sysLog.setUsername(params.getString("username")); + } + + // 保存 logRepository.save(sysLog); } /** * 根据方法和传入的参数获取请求参数 */ - private String getParameter(Method method, Object[] args) { - List argList = new ArrayList<>(); + private JSONObject getParameter(Method method, Object[] args) { + JSONObject params = new JSONObject(); Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { - // 过滤掉不能序列化的类型: MultiPartFile + // 过滤掉 MultiPartFile if (args[i] instanceof MultipartFile) { continue; } - //将RequestBody注解修饰的参数作为请求参数 + // 过滤掉 HttpServletResponse + if (args[i] instanceof HttpServletResponse) { + continue; + } + // 过滤掉 HttpServletRequest + if (args[i] instanceof HttpServletRequest) { + continue; + } + // 将RequestBody注解修饰的参数作为请求参数 RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class); if (requestBody != null) { - argList.add(args[i]); - } - //将RequestParam注解修饰的参数作为请求参数 - RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class); - if (requestParam != null) { - Map map = new HashMap<>(2); + params.putAll((JSONObject) JSON.toJSON(args[i])); + } else { String key = parameters[i].getName(); - if (!StringUtils.isEmpty(requestParam.value())) { - key = requestParam.value(); - } - map.put(key, args[i]); - argList.add(map); + params.put(key, args[i]); } } - if (argList.isEmpty()) { - return ""; + // 遍历敏感字段数组并替换值 + Set keys = params.keySet(); + for (String key : SENSITIVE_KEYS) { + if (keys.contains(key)) { + params.put(key, "******"); + } } - return argList.size() == 1 ? JSON.toJSONString(argList.get(0)) : JSON.toJSONString(argList); + // 返回参数 + return params; } @Override diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java index 812f57ac..46b140a9 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/TokenProvider.java @@ -18,7 +18,6 @@ package me.zhengjie.modules.security.security; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.IdUtil; -import cn.hutool.crypto.digest.DigestUtil; import io.jsonwebtoken.*; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; @@ -47,7 +46,7 @@ public class TokenProvider implements InitializingBean { private JwtBuilder jwtBuilder; private final RedisUtils redisUtils; private final SecurityProperties properties; - public static final String AUTHORITIES_UUID_KEY = "uuid"; + public static final String AUTHORITIES_UUID_KEY = "uid"; public static final String AUTHORITIES_UID_KEY = "userId"; public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) { @@ -79,7 +78,7 @@ public class TokenProvider implements InitializingBean { // 设置用户ID claims.put(AUTHORITIES_UID_KEY, user.getUser().getId()); // 设置UUID,确保每次Token不一样 - claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID()); + claims.put(AUTHORITIES_UUID_KEY, IdUtil.objectId()); return jwtBuilder .setClaims(claims) .setSubject(user.getUsername()) @@ -136,7 +135,16 @@ public class TokenProvider implements InitializingBean { */ public String loginKey(String token) { Claims claims = getClaims(token); - String md5Token = DigestUtil.md5Hex(token); - return properties.getOnlineKey() + claims.getSubject() + "-" + md5Token; + return properties.getOnlineKey() + claims.getSubject() + ":" + getId(token); + } + + /** + * 获取登录用户TokenKey + * @param token / + * @return / + */ + public String getId(String token) { + Claims claims = getClaims(token); + return claims.get(AUTHORITIES_UUID_KEY).toString(); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java index c27a554c..553c26cc 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/OnlineUserService.java @@ -53,11 +53,12 @@ public class OnlineUserService { public void save(JwtUserDto jwtUserDto, String token, HttpServletRequest request){ String dept = jwtUserDto.getUser().getDept().getName(); String ip = StringUtils.getIp(request); + String id = tokenProvider.getId(token); String browser = StringUtils.getBrowser(request); String address = StringUtils.getCityInfo(ip); OnlineUserDto onlineUserDto = null; try { - onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date()); + onlineUserDto = new OnlineUserDto(id, jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date()); } catch (Exception e) { log.error(e.getMessage(),e); } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/dto/OnlineUserDto.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/dto/OnlineUserDto.java index 826f203d..354ee066 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/service/dto/OnlineUserDto.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/service/dto/OnlineUserDto.java @@ -30,6 +30,9 @@ import java.util.Date; @NoArgsConstructor public class OnlineUserDto { + @ApiModelProperty(value = "Token编号") + private String uid; + @ApiModelProperty(value = "用户名") private String userName; diff --git a/eladmin-system/src/main/resources/spy.properties b/eladmin-system/src/main/resources/spy.properties index 7b60caf6..fc814804 100644 --- a/eladmin-system/src/main/resources/spy.properties +++ b/eladmin-system/src/main/resources/spy.properties @@ -23,7 +23,7 @@ outagedetectioninterval=2 filter=true # 过滤 Log 时所排除的 sql 关键字,以逗号分隔 -exclude=select 1 +exclude=SELECT 1,INSERT INTO sys_log # 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset. excludecategories=info,debug,result,commit,resultset \ No newline at end of file