依赖
脱敏包
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>sensitive-logback</artifactId>
<version>1.7.0</version>
</dependency>
logback 依赖包
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
配置
logback.xml
<configuration>
<!-- 基于 converter -->
<conversionRule conversionWord="sensitive" converterClass="com.github.houbb.sensitive.logback.converter.SensitiveLogbackConverter" />
<!-- 使用 converter -->
<appender name="STDOUTConverter" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %sensitive%n</pattern>
</encoder>
</appender>
<!-- 使用 layout -->
<appender name="STDOUTLayout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="com.github.houbb.sensitive.logback.layout.SensitiveLogbackLayout">
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</layout>
</appender>
<!-- 设置根日志级别为DEBUG,并将日志输出到控制台 -->
<root level="DEBUG">
<appender-ref ref="STDOUTConverter"/>
<appender-ref ref="STDOUTLayout"/>
</root>
</configuration>
项目里面的logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProperty scope="context" name="app.name" source="spring.application.name"/>
<!-- 基于 converter -->
<conversionRule conversionWord="sensitive" converterClass="com.github.houbb.sensitive.logback.converter.SensitiveLogbackConverter" />
<property name="APP_NAME" value="${app.name}"/>
<property name="LOG_PATH" value="${user.home}/${APP_NAME}/logs"/>
<property name="LOG_FILE" value="${LOG_PATH}/application.log"/>
<!-- 日志格式配置 -->
<property name="FILE_LOG_PATTERN" value="%d %-5level [%thread %logger - %sensitive%n"/>
<appender name="APPLICATION"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>7</maxHistory>
<maxFileSize>50MB</maxFileSize>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="APPLICATION"/>
</root>
</configuration>
前台数据展示隐藏
脱敏注解
public class Example {
@SensitiveStrategyChineseName
private String username;
@SensitiveStrategyPassword
private String password;
@SensitiveStrategyPassport
private String passport;
@SensitiveStrategyIdNo
private String idNo;
@SensitiveStrategyCardId
private String bandCardId;
@SensitiveStrategyPhone
private String phone;
@SensitiveStrategyEmail
private String email;
@SensitiveStrategyAddress
private String address;
@SensitiveStrategyBirthday
private String birthday;
@SensitiveStrategyGps
private String gps;
@SensitiveStrategyIp
private String ip;
@SensitiveStrategyMaskAll
private String maskAll;
@SensitiveStrategyMaskHalf
private String maskHalf;
@SensitiveStrategyMaskRange
private String maskRange;
}
拦截器
运行getUserInfo的时候
@GetMapping("/getUserInfo")
public Result<UserInfo> getUserInfo() {
String userId = (String) StpUtil.getLoginId();
UserQueryRequest request = new UserQueryRequest();
request.setUserId(Long.valueOf(userId));
User user = userService.findById(Long.valueOf(userId));
if (user == null) {
throw new UserException(USER_NOT_EXIST);
}
return Result.success(UserConvertor.INSTANCE.mapToVo(user));
}
根据Result类型的返回结果进行拦截,通过 SensitiveUtil.desCopy(UserInfo)进行脱敏
@ControllerAdvice
public class SensitiveResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
// 只对特定类型的返回值执行处理逻辑,这里可以根据需要调整判断条件
return Result.class.isAssignableFrom(returnType.getParameterType());
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
// 如果返回的对象是UserInfo,进行脱敏处理
switch (((Result<?>) body).getData()) {
case UserInfo userInfo:
((Result<UserInfo>) body).setData(SensitiveUtil.desCopy(userInfo));
default:
return body;
}
return body;
}