SpringBoot如何优雅地实现返回数据脱敏

38 阅读1分钟

架包引入

cn.hutool hutool-all 5.8.16

package com.poi.desensitize.annotation;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.poi.desensitize.enums.SensitizeRuleEnums; import com.poi.desensitize.serializer.SensitiveJsonSerializer;

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

/**

  • @author hzd
  • @description 数据脱敏注解 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using = SensitiveJsonSerializer.class) public @interface Sensitize { SensitizeRuleEnums rule(); }

数据脱敏枚举

package com.poi.desensitize.enums;

import cn.hutool.core.util.DesensitizedUtil; import java.util.function.Function;

/**

  • @author hzd
  • @description 数据脱敏枚举 / public enum SensitizeRuleEnums { /*
    • 用户id脱敏 */ USER_ID(s -> String.valueOf(DesensitizedUtil.userId())),

/**

  • 中文姓名脱敏 */ CHINESE_NAME(DesensitizedUtil::chineseName),

/**

  • 身份证脱敏 */ ID_CARD(s -> DesensitizedUtil.idCardNum(s, 3, 4)),

/**

  • 固定电话 */ FIXED_PHONE(DesensitizedUtil::fixedPhone),

/**

  • 手机号脱敏 */ MOBILE_PHONE(DesensitizedUtil::mobilePhone),

/**

  • 地址脱敏 */ ADDRESS(s -> DesensitizedUtil.address(s, 8)),

/**

  • 电子邮箱脱敏 */ EMAIL(DesensitizedUtil::email),

/**

  • 密码脱敏 */ PASSWORD(DesensitizedUtil::password),

/**

  • 中国车牌脱敏 */ CAR_LICENSE(DesensitizedUtil::carLicense),

/**

  • 银行卡脱敏 */ BANK_CARD(DesensitizedUtil::bankCard);

/**

  • 可自行添加其他脱敏策略..... */ private final Function<String, String> sensitize;

public Function<String, String> sensitize() { return sensitize; }

SensitizeRuleEnums(Function<String, String> sensitize) { this.sensitize = sensitize; } }

对返回前台的数据进行脱敏

package com.poi.desensitize.serializer;

import cn.hutool.core.util.DesensitizedUtil; 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 com.poi.desensitize.annotation.Sensitize; import com.poi.desensitize.enums.SensitizeRuleEnums;

import java.io.IOException; import java.util.Objects;

/**

  • @author hzd
  • @description 序列化类作用:对返回前台的数据进行脱敏 */ public class SensitiveJsonSerializer extends JsonSerializer implements ContextualSerializer {

private SensitizeRuleEnums rule;

@Override public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(rule.sensitize().apply(value)); }

@Override public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException { Sensitize annotation = beanProperty.getAnnotation(Sensitize.class); if (Objects.nonNull(annotation) && Objects.equals(String.class, beanProperty.getType().getRawClass())) { this.rule = annotation.rule(); return this; } return null; } }

测试对象

/**

  • @author hzd
  • @description 测试对象 */ @Data public class User { private Long id;

private String name;

@Sensitize(rule = SensitizeRuleEnums.EMAIL) private String email;

@Sensitize(rule = SensitizeRuleEnums.PASSWORD) private String password;

@Sensitize(rule = SensitizeRuleEnums.MOBILE_PHONE) private String phone; }

测试接口

/**

  • @author hzd
  • @description 测试对象 */ package com.poi.desensitize.controller;

import com.poi.desensitize.model.User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;

/**

  • @author hzd
  • @description 测试类 */ @RestController public class TestController {

@GetMapping("getUser") public User getUser(){ User user = new User(); user.setId(1L); user.setName("james"); user.setEmail("123456789@qq.com"); user.setPhone("13211975672"); user.setPassword("123456");

return user;

} }