脱敏工具

发布于 2023-04-12  991 次阅读


使用方式:通过在DTO中或者VO中增加注解,并在注解中声明脱敏方式

通过以上方式实现在前端返回时,序列化过程中,将字符串的内容进行脱敏处理。比如手机号、地址、用户姓名等。

  • 首先定义一个枚举规定脱敏类型
package com.ideatech.common.serializer;


/**
 * @author tsj
 * @desc 脱敏规则枚举
 */

public enum DesensitizationEnum {


    DEFAULE("默认"),
    //用户id
    USER_ID("用户id"),
    //中文名
    CHINESE_NAME("中文名"),
    //身份证号
    ID_CARD("身份证号"),
    //座机号
    FIXED_PHONE("座机号"),
    //手机号
    MOBILE_PHONE("手机号"),
    //地址
    ADDRESS("地址"),
    //电子邮件
    EMAIL("电子邮件"),
    //密码
    PASSWORD("密码"),
    //中国大陆车牌,包含普通车辆、新能源车辆
    CAR_LICENSE("车牌"),
    //银行卡
    BANK_CARD("银行卡");


    private String desc;

    //
    DesensitizationEnum(String desc) {
        this.desc = desc;
    }
}
  • 创建一个注解,表明需要进行脱敏的字段
package com.ideatech.common.serializer;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.springframework.core.annotation.AliasFor;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizationJsonSerializer.class)
public @interface Desensitization {
    @AliasFor("value")
    DesensitizationEnum desen() default DesensitizationEnum.DEFAULE;

    @AliasFor("desen")
    DesensitizationEnum value() default DesensitizationEnum.DEFAULE;

}
  • 创建配置类,修改序列化时根据注解进行字符串的替换修改
package com.ideatech.common.serializer;


import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.StrUtil;
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 java.io.IOException;
import java.util.Objects;
import java.util.Optional;

/**
 * @author tsj
 * @desc 脱敏序列化
 */
public class DesensitizationJsonSerializer extends JsonSerializer implements ContextualSerializer {

    private DesensitizationEnum desensitizationEnum;

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value != null && value instanceof String) {
            if (desensitizationEnum == null) {
                gen.writeString(value.toString());
                return;
            }
            String name = desensitizationEnum.name();
            if (Objects.equals(name, DesensitizationEnum.DEFAULE.name())) {
                gen.writeString(customerDen(value));
                return;
            }
            gen.writeString(DesensitizedUtil.desensitized(value.toString(), DesensitizedUtil.DesensitizedType.valueOf(name)));
        } else {
            gen.writeObject(value);
        }
    }

    /**
     * 自定义
     *
     * @param value
     * @return
     */
    private String customerDen(Object value) {
        String str = value.toString();
        // frontLen 字符串前面保留位数
        // endLen 字符串后面保留位数
        int frontLen = 1;
        int endLen = 1;
        if (StrUtil.isBlank(str)) {
            return str;
        }
        if (str.length() <= 3) {
            int len = str.length() - frontLen;
            String xing = "";
            for (int i = 0; i < len; i++) {
                xing += '*';
            }
            return str.substring(0, frontLen) + xing;
        }
        // if (str.length > 3 && str.length <6){
        //
        // }
        if (str.length() >= 6 && str.length() <= 10) {
            frontLen = 2;
            endLen = 2;
        }
        if (str.length() >= 11) {
            frontLen = 3;
            endLen = 4;
        }

        int len = str.length() - frontLen - endLen;
        String xing = "";
        for (int i = 0; i < len; i++) {
            xing += '*';
        }
        return str.substring(0, frontLen) + xing + str.substring(str.length() - endLen);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) throws JsonMappingException {
        //判断beanProperty是不是空
        if (property == null) {
            return serializerProvider.findNullValueSerializer(property);
        }
        if (Objects.equals(property.getType().getRawClass(), String.class)) {
            Desensitization annotation = property.getAnnotation(Desensitization.class);
            if (annotation != null) {
                desensitizationEnum = annotation.desen();
                return this;
            }
        }
        return serializerProvider.findValueSerializer(property.getType(), property);
    }
}

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。