SpringBoot接口数据如何实现优雅的脱敏问题
作者:@会飞的羊
这篇文章主要介绍了SpringBoot接口数据如何实现优雅的脱敏问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
实现方案:自定义注解 + Jackson序列化器
1.具体代码
自定义脱敏注解:
package org.springblade.common.annotation; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.springblade.common.config.SensitiveJsonSerializer; import org.springblade.common.enums.SensitiveTypeEnum; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 脱敏注解 * * @author hf * @since 2023/6/14 **/ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonSerialize(using = SensitiveJsonSerializer.class) public @interface Desensitized { /** * 脱敏类型(规则) */ SensitiveTypeEnum type(); }
脱敏类型枚举类:支持用户名、手机号、身份证号、地址
package org.springblade.common.enums; import java.util.function.Function; /** * 脱敏类型枚举 * * @author hf * @since **/ public enum SensitiveTypeEnum { /** * 用户名 */ USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), /** * 身份证 */ ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")), /** * 手机号 */ MOBILE_PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), /** * 地址 */ ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****")); private final Function<String, String> desensitizer; SensitiveTypeEnum(Function<String, String> desensitizer) { this.desensitizer = desensitizer; } public Function<String, String> desensitizer() { return desensitizer; } }
序列化注解自定义实现:
package org.springblade.common.config; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import org.springblade.common.annotation.Desensitized; import org.springblade.common.enums.SensitiveTypeEnum; import java.io.IOException; import java.util.Objects; /** * 序列化注解自定义实现 * JsonSerializer<String>:指定String 类型,serialize()方法用于将修改后的数据载入 */ public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer { private SensitiveTypeEnum strategy; @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(strategy.desensitizer().apply(value)); } /** * 获取属性上的注解属性 */ @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { Desensitized annotation = property.getAnnotation(Desensitized.class); if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) { this.strategy = annotation.type(); return this; } return prov.findValueSerializer(property.getType(), property); } }
2.使用方法
添加注解@Desensitized
在需要进行脱敏的字段上添加@Desensitized注解,并选择具体的脱敏类型。
示例如下:
/** * 手机 */ @Desensitized(type = SensitiveTypeEnum.MOBILE_PHONE) private String phone; /** * 身份证号 */ @Desensitized(type = SensitiveTypeEnum.ID_CARD) private String idNo;
3.脱敏结果
3.1脱敏前数据:
{ "phone": "13924369234", "idNo": "1210103199603282410", }
3.2脱敏后数据:
{ "phone": "139****9234", "idNo": "1210************10", }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。