首页 > 其他分享 >一个注解优雅的实现 接口数据脱敏

一个注解优雅的实现 接口数据脱敏

时间:2022-08-25 11:03:24浏览次数:57  
标签:接口 strategy Sensitive SensitiveStrategy 注解 public 脱敏

通常接口返回值中的一些敏感数据也是要脱敏的,比如身份证号、手机号码、地址.....通常的手段就是用*隐藏一部分数据,当然也可以根据自己需求定制。
言归正传,如何优雅的实现呢?有两种实现方案,如下:
整合Mybatis插件,在查询的时候针对特定的字段进行脱敏 整合Jackson,在序列化阶段对特定字段进行脱敏 基于Sharding Sphere实现数据脱敏
第一种方案网上很多实现方式,下面演示第二种,整合Jackson。

  1. 自定义一个Jackson注解

需要自定义一个脱敏注解,一旦有属性被标注,则进行对应得脱敏,如下:

/**
 * 自定义jackson注解,标注在属性上
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
    //脱敏策略
    SensitiveStrategy strategy();
}

2. 定制脱敏策略

针对项目需求,定制不同字段的脱敏规则,比如手机号中间几位用*替代,如下:

/**
 * 脱敏策略,枚举类,针对不同的数据定制特定的策略
 */
public enum SensitiveStrategy {
    /**
     * 用户名
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
    /**
     * 身份证
     */
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
    /**
     * 手机号
     */
    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;

    SensitiveStrategy(Function<String, String> desensitizer) {
        this.desensitizer = desensitizer;
    }

    public Function<String, String> desensitizer() {
        return desensitizer;
    }
}
 以上只是提供了部分,具体根据自己项目要求进行配置。
 3. 定制JSON序列化实现

下面将是重要实现,对标注注解@Sensitive的字段进行脱敏,实现如下:

/**
 * 序列化注解自定义实现
 * JsonSerializer<String>:指定String 类型,serialize()方法用于将修改后的数据载入
 */
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
    private SensitiveStrategy 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 {

        Sensitive annotation = property.getAnnotation(Sensitive.class);
        if (Objects.nonNull(annotation)&&Objects.equals(String.class, property.getType().getRawClass())) {
            this.strategy = annotation.strategy();
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);

    }
}
4. 定义Person类,对其数据脱敏

使用注解@Sensitive注解进行数据脱敏,代码如下:

@Data
public class Person {
    /**
     * 真实姓名
     */
    @Sensitive(strategy = SensitiveStrategy.USERNAME)
    private String realName;
    /**
     * 地址
     */
    @Sensitive(strategy = SensitiveStrategy.ADDRESS)
    private String address;
    /**
     * 电话号码
     */
    @Sensitive(strategy = SensitiveStrategy.PHONE)
    private String phoneNumber;
    /**
     * 身份证号码
     */
    @Sensitive(strategy = SensitiveStrategy.ID_CARD)
    private String idCard;
}

5. 模拟接口测试

以上4个步骤完成了数据脱敏的Jackson注解,下面写个controller进行测试,代码如下:

@RestController
public class TestController {
    @GetMapping("/test")
    public Person test(){
        Person user = new Person();
        user.setRealName("不才陈某");
        user.setPhoneNumber("19796328206");
        user.setAddress("浙江省杭州市....");
        user.setIdCard("4333333333334334333");
        return user;
    }
}

原文链接:https://zhuanlan.zhihu.com/p/532289210

标签:接口,strategy,Sensitive,SensitiveStrategy,注解,public,脱敏
From: https://www.cnblogs.com/azhqiang/p/16623531.html

相关文章

  • 学会了JsonPath,你的Python接口脚本才算完整
    每天进步一点点,关注我们哦,每天分享测试技术文章本文章出自【码同学软件测试】码同学公众号:自动化软件测试,领取资料可加:magetest码同学抖音号:小码哥聊软件测试01Jsonpat......
  • restfulAPI接口规范/django rest_Framework_环境
    一.RESTFUlAPI设计1).域名应该将api部署在专用域名下https://www.baidu.com/api/2).版本应该将API版本号放到路径中https://www.baidu.com/api/1.0/loginhttps:......
  • 脱敏工具类
    importjava.io.Serializable;/***脱敏工具类*脱敏规则:可显示字符*姓名:前1*电话:前3后4*身份证:前6后3*地址:省、市*银行账号:后4*/publicclassD......
  • java设计思路-项目中两种接口设计方法,请讲出优缺点
    结论:通过函数式接口,可以任意组装成不同粒度的接口,使用起来很灵活,强烈推荐。第一种设计方法:packagecom.iit.service.user;importcom.iit.domain.User;//这是第1种......
  • web项目开发写接口时,为什么需要在关键位置打印日志-2022新项目
    一、业务场景最近在开发新功能,新功能主要就是写app的首页查询接口,接口比较多有十几个,首页会有各种查询,新增操作比较少。由于用户量比较大,据说并发量不小,所以首页的很......
  • JS doc 接口文档生成器
    前言项目中使用到需要把js方法生成接口文档,使用到了JSdoc这个工具,使用该工具生成文档,需要在方法里加入注释,根据注释说明生成文档,这里顺便记录一下使用过程,模拟了一些j......
  • SpringMVC 常用注解
    @requestMapping用于请求url映射。 @RequestBody注解实现接收http请求的json数据,将json数据转换为java对象。 @ResponseBody注解实现将controller方......
  • 2022年第 12期《python接口web自动化+测试开发》课程,9月17号开学!
    2022年第12期《python接口web自动化+测试开发》课程,9月17号开学(课程全面升级!)主讲老师:上海-悠悠上课方式:微信群视频在线教学,方便交流本期上课时间:2022年9月17号-2022......
  • BeanFactory接口体系整理
    BeanFactory体系结构 BeanFactoryBeanFactory作为Spring容器的顶层接口,那么它的作用一定是最简单,最核心的,特性如下:基础的容器定义了作用域的概念集成了环境配置......
  • spring接口多实现类,该依赖注入哪一个?
    一、问题的描述在实际的系统应用开发中我经常会遇到这样的一类需求,相信大家在工作中也会经常遇到:同一个系统在多个省份部署。一个业务在北京是一种实现方式,是基于北京......