SpringBoot接口数据如何实现优雅的脱敏问题

 更新时间:2023年12月08日 09:35:58   作者:@会飞的羊  
这篇文章主要介绍了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",
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

最新评论