SpringBoot实战:轻松实现接口数据脱敏

news2024/9/22 13:21:48

文章目录

  • 引言
  • 一、接口数据脱敏概述
    • 1.1 接口数据脱敏的定义
    • 1.2 接口数据脱敏的重要性
    • 1.3 接口数据脱敏的实现方式
  • 二、开发环境
  • 三、实现接口返回数据脱敏
    • 3.1 添加依赖
    • 3.2 创建自定义注解
    • 3.3 定义脱敏枚举类
    • 3.4 创建自定义序列化类
  • 四、测试
    • 4.1 编写测试代码
    • 4.2 测试
  • 五、总结

在这里插入图片描述

引言

在当今的信息化时代,数据安全尤为重要。接口返回数据脱敏是一种重要的数据保护手段,可以防止敏感信息通过接口返回给客户端,降低数据泄露的风险。本文旨在探讨如何在SpringBoot应用程序中实现接口返回数据脱敏。我们将介绍一种基于自定义注解结合Hutool脱敏工具类的方案,以实现SpringBoot中的接口返回数据脱敏。

一、接口数据脱敏概述

1.1 接口数据脱敏的定义

接口数据脱敏是指在Web应用程序的API接口返回数据时,对包含敏感信息的字段进行处理,使其部分或全部信息被隐藏或替换,以防止敏感信息的泄露。这个过程通常不会改变数据的原始格式,而是通过特定的算法或规则,将敏感部分替换为特定字符(如星号*)或者保留部分信息。

1.2 接口数据脱敏的重要性

数据脱敏的重要性主要体现在以下几个方面:

  1. 保护用户隐私: 对于姓名、身份证号、手机号等个人敏感信息进行脱敏,可以有效保护用户隐私,防止信息被滥用。
  2. 遵守法律法规: 许多国家和地区都制定了严格的数据保护法规,如欧盟的GDPR和中国的《个人信息保护法》。实施数据脱敏有助于企业合规经营。
  3. 降低安全风险: 通过脱敏处理,即使数据不慎泄露,也能最大限度地减少敏感信息被盗用的风险。
  4. 支持数据共享: 在保护隐私的同时,脱敏数据仍然保留了一定的分析价值,有利于数据的安全共享和利用。

1.3 接口数据脱敏的实现方式

  1. 手动脱敏:在业务逻辑层直接对敏感数据进行处理。这种方式灵活但容易遗漏,且代码重复率高。

  2. AOP(面向切面编程):通过切面拦截返回数据,统一处理敏感字段。这种方式可以集中管理脱敏逻辑,但可能影响性能。

  3. 自定义序列化器:利用JSON序列化框架(如Jackson)的自定义序列化器来处理敏感字段。这种方式性能较好,且与业务逻辑解耦。

  4. 注解+反射:通过自定义注解标记需要脱敏的字段,然后利用反射机制在运行时进行脱敏处理。这种方式使用简单,易于维护。

本文将重点介绍如何结合自定义注解和Hutool工具类来实现接口数据脱敏。

二、开发环境

  • JDK版本:JDK 17
  • Spring Boot版本:Spring Boot 3.2.2
  • 构建工具:Maven

三、实现接口返回数据脱敏

3.1 添加依赖

首先在 pom.xml 文件中添加必要的依赖:

    <!-- Hutool工具包 -->    
<dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.25</version>
    </dependency>
    <!-- Jackson依赖 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.2</version>
    </dependency>

3.2 创建自定义注解

接下来,我们创建一个自定义注解 @Desensitize

/**
 * 用于标记字段需要进行脱敏处理的注解
 *
 * @author shijun
 * @date 2024/07/09
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizeSerializer.class)
public @interface Desensitize {

    /**
     * 脱敏类型
     */
    DesensitizeType type() default DesensitizeType.DEFAULT;

    /**
     * 脱敏起始位置
     */
    int startInclude() default 0;

    /**
     * 脱敏结束位置
     */
    int endExclude() default 0;
    
}

3.3 定义脱敏枚举类

然后,定义枚举类 DesensitizeType 来定义字段的脱敏类型:

/**
 * 脱敏类型枚举类
 */
public enum DesensitizeType {

    /**
     * 默认脱敏
     */
    DEFAULT,
    /**
     * 自定义脱敏
     */
    CUSTOM_RULE,
    /**
     * 手机号脱敏
     */
    PHONE,
    /**
     * 电子邮件脱敏
     */
    EMAIL,
    /**
     * 身份证号脱敏
     */
    ID_CARD,
    /**
     * 银行卡号脱敏
     */
    BANK_CARD,
    /**
     * 地址脱敏
     */
    ADDRESS,
    /**
     * 中文姓名脱敏
     */
    CHINESE_NAME,
    /**
     * 密码脱敏
     */
    PASSWORD,
}

3.4 创建自定义序列化类

Hutool支持的脱敏数据类型包括:

  1. 用户id
  2. 中文姓名
  3. 身份证号
  4. 座机号
  5. 手机号
  6. 地址
  7. 电子邮件
  8. 密码
  9. 中国大陆车牌,包含普通车辆、新能源车辆
  10. 银行卡

整体来说,所谓脱敏就是隐藏掉信息中的一部分关键信息,用*代替。大家可以自己看一看DesensitizedUtil类中方法,其实就是replace方法和hide方法的使用,想要自定义规则进行隐藏可以仿照进行实现。

/**
 * 脱敏序列化器,用于在序列化字符串时根据不同的脱敏类型进行数据脱敏。
 *
 * @author shijun
 * @date 2024/07/08
 */
public class DesensitizeSerializer extends JsonSerializer<String> implements ContextualSerializer {

    /**
     * 脱敏类型,默认为DEFAULT
     */
    private DesensitizeType type;
    /**
     * 脱敏起始位置
     */
    private int startInclude;
    /**
     * 脱敏结束位置
     */
    private int endExclude;

    public DesensitizeSerializer() {
        this.type = DesensitizeType.DEFAULT;
    }


    public DesensitizeSerializer(DesensitizeType type) {
        this.type = type;
    }

    /**
     * 序列化字符串时调用,根据脱敏类型对字符串进行相应的脱敏处理。
     *
     * @param value       待序列化的字符串
     * @param gen         JSON生成器,用于写入处理后的字符串
     * @param serializers 序列化器提供者,用于获取其他序列化器
     * @throws IOException 如果序列化过程中发生I/O错误
     */
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        switch (type) {
            case CUSTOM_RULE:
                // 这里是对字符串的startInclude到endExclude字段进行隐藏处理,如果想要实现两端保留,可以考虑使用StrUtil的replace方法
                gen.writeString(StrUtil.hide(value, startInclude, endExclude));
                break;
            case PHONE:
                gen.writeString(DesensitizedUtil.mobilePhone(value));
                break;
            case EMAIL:
                gen.writeString(DesensitizedUtil.email(value));
                break;
            case ID_CARD:
                gen.writeString(DesensitizedUtil.idCardNum(value, 1, 2));
                break;
            case BANK_CARD:
                gen.writeString(DesensitizedUtil.bankCard(value));
                break;
            case ADDRESS:
                gen.writeString(DesensitizedUtil.address(value, 8));
                break;
            case CHINESE_NAME:
                gen.writeString(DesensitizedUtil.chineseName(value));
                break;
            case PASSWORD:
                gen.writeString(DesensitizedUtil.password(value));
                break;
            default:
                gen.writeString(value);
                break;
        }
    }

    /**
     * 根据上下文信息创建自定义的序列化器,用于处理带有@Desensitize注解的属性。
     *
     * @param prov     序列化器提供者,用于获取其他序列化器
     * @param property 当前属性的信息,用于获取注解和属性类型
     * @return 自定义的序列化器实例
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
        if (property != null) {
            Desensitize annotation = property.getAnnotation(Desensitize.class);
            if (annotation != null) {
                this.type = annotation.type();
                if (annotation.type() == DesensitizeType.CUSTOM_RULE) {
                    this.startInclude = annotation.startInclude();
                    this.endExclude = annotation.endExclude();
                }
            }
        }
        return this;
    }

}

代码分析:

  • serialize方法在序列化字符串时被调用,根据脱敏类型对字符串进行相应的脱敏处理。根据不同的脱敏类型,使用不同的处理方法对字符串进行脱敏,并将处理后的字符串写入JSON生成器中。
  • createContextual方法根据上下文信息创建自定义的序列化器,用于处理带有@Desensitize注解的属性。它通过获取注解中的脱敏类型和自定义规则的起始位置和结束位置,对实例进行相应的设置,并返回自定义的序列化器实例。

这个序列化器的主要用途是在 JSON 序列化过程中自动对标记了 @Desensitize 注解的字段进行脱敏处理。

四、测试

4.1 编写测试代码

  1. 编写实体类
@Data
public class UserDTO {

    /**
     * 用户姓名
     */
    @Desensitize(type = DesensitizeType.CHINESE_NAME)
    private String name;

    /**
     * 用户手机号
     */
    @Desensitize(type = DesensitizeType.PHONE)
    private String phoneNumber;

    /**
     * 用户电子邮件地址
     */
    @Desensitize(type = DesensitizeType.EMAIL)
    private String email;

    /**
     * 用户密码
     */
    @Desensitize(type = DesensitizeType.PASSWORD)
    private String password;

    /**
     * 用户身份证号码
     */
    @Desensitize(type = DesensitizeType.ID_CARD)
    private String idCard;

    /**
     * 用户银行卡号
     */
    @Desensitize(type = DesensitizeType.BANK_CARD)
    private String bankCard;

    /**
     * 用户地址
     */
    @Desensitize(type = DesensitizeType.ADDRESS)
    private String address;

    /**
     * 游戏名称
     */
    @Desensitize(type = DesensitizeType.CUSTOM_RULE, startInclude = 2, endExclude = 6)
    private String gameName;
}

  1. 编写测试接口
@RestController
@RequestMapping("/test")
public class TestController {
    
    @GetMapping("/desensitize")
    public UserDTO getUser() {
        UserDTO userDTO = new UserDTO();
        userDTO.setName("孙大圣");
        userDTO.setEmail("shijun@163.com");
        userDTO.setPhoneNumber("12345678901");
        userDTO.setPassword("123456");
        userDTO.setAddress("辽宁省盘锦市兴隆台区红村乡441号");
        userDTO.setIdCard("447465200912089605");
        userDTO.setBankCard("6217000000000000000");
        userDTO.setGameName("超级无敌大铁锤");
        return userDTO;
    }

}

4.2 测试

image-20240709170909054

五、总结

在本文中,我们探讨了在SpringBoot应用程序中实现数据脱敏的重要性,并提出了通过自定义注解结合Hutool脱敏工具类实现数据脱敏的解决方案。通过这个方案,我们能够有效地对敏感数据进行脱敏处理,从而保护用户隐私和数据安全,希望对大家有所帮助😊。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1911122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在 SwiftUI 中开发定制 MapKit 功能

文章目录 介绍地图样式imagery-map 地图交互地图控件总结 介绍 在上一篇文章中&#xff0c;我们探讨了 SwiftUI 中新的 MapKit API 的基础知识。现在&#xff0c;让我们深入 MapKit API 的定制点&#xff0c;以便根据我们的需求定制地图呈现。 地图样式 新的 MapKit API 引入…

晶体振荡器:频率的广度与应用的深度

晶体振荡器&#xff0c;以其无与伦比的频率稳定性和广泛的应用范围&#xff0c;成为现代电子工程的基石。从低至0.0320MHz的细腻频率到高达1075MHz以上的雄壮音符&#xff0c;晶体振荡器跨越了广阔频谱&#xff0c;为计时、通信、高级电子系统乃至宇宙探索提供了精准的时间基准…

PyCharm在线版,一周使用总结!!!

前言 过去一周&#xff0c;对pycharm在线版进行了使用&#xff0c;对云原生开发工具有了全新的认识&#xff0c;云原生开发是一种现代化的软件开发和部署方法&#xff0c;它充分利用了云计算的优势&#xff0c;特别是容器化、微服务、持续集成/持续部署&#xff08;CI/CD&…

【界面态】霍尔效应表征氮化对SiC/SiO2界面陷阱的影响

引言 引言主要介绍了硅碳化物&#xff08;SiC&#xff09;金属-氧化物-半导体场效应晶体管&#xff08;MOSFETs&#xff09;作为新一代高压、低损耗功率器件的商业化背景。SiC MOSFETs因其优越的电气特性&#xff0c;在高电压和高温应用领域具有巨大的潜力。然而&#xff0c;尽…

GitHub开源推荐:AI加持的Notion风格编辑器Novel

在现代内容创作和协作平台中&#xff0c;Notion无疑是备受推崇的一款工具。而现在&#xff0c;有一个开源项目——Novel&#xff0c;它不仅提供了类似Notion的所见即所得&#xff08;WYSIWYG&#xff09;编辑功能&#xff0c;还集成了强大的AI自动补全功能&#xff0c;极大地提…

Android Constant expression required (case R.id.xxx)

gradle更新到8.0后&#xff0c;遇到了这个报错 有两种解决方式&#xff1a; 1、在gradle.properties中添加下面代码 android.nonFinalResIdsfalse 2、使用if-else来判断 int id view.getId(); if (id R.id.setting_iv_back) {} else if (id R.id.setting_tv_clear) {}

websocket推送消息,模拟推送

上一篇文章&#xff1a;什么是webSocket&#xff1f;以及它的一些相关理论知识 背景&#xff1a; MQTT 的发布/订阅模式与 WebSocket 的双向通信特性相结合。 通过将 MQTT 与 WebSocket 结合使用&#xff0c;可以在 Web 应用中实现高效、实时的消息传输&#xff0c;特别适用于…

【Python_GUI】tkinter模块、创建空白窗口

tkinter是使用Python进行窗口视觉设计的模块&#xff0c;它是Python的标准Tk GUI工具包的接口&#xff0c;在安装Python时&#xff0c;就自动安装了该模块。 使用tkinter模块开发时&#xff0c;最核心的就是各种组件的使用。生活中玩积木时&#xff0c;通过将不同形状的木板进…

Linux进程管理Part2

Linux进程控制Part2 文章目录 Linux进程控制Part2Fork()函数详解简单描述 fork函数的使用进程退出的方式_exit函数exit函数return 退出 进程等待进程等待的方法 kill的使用进程替换简单描述命名原理 END Fork()函数详解 FORK(2) Linux Programmer’s Manual FORK(2) NAME for…

计算机的核心工作机制

前言 本篇不介绍代码&#xff0c;主要是理解计算机的一些核心工作机制。想了解更多请跳转-->【【计算机科学速成课】[40集全/精校] - Crash Course Computer Science】 冯诺依曼体系结构 由计算机之父之一冯诺依曼提出的计算机内部构造的基本组成&#xff0c;而现在大多数…

前端使用Vue和Element实现可拖动弹框效果,且不影响底层元素操作(可拖拽的视频实时播放弹框,底层元素可以正常操作)

简述&#xff1a;在前端开发中&#xff0c;弹框和实时视频播放是常见的需求。这里来简单记录一下&#xff0c;如何使用Vue.js和Element UI实现一个可拖动的弹框&#xff0c;并在其中播放实时视频。同时&#xff0c;确保在拖拽弹框时&#xff0c;底层元素仍然可以操作。 一、项目…

用python生成词频云图(python实例二十一)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.词频云图 3.1 代码构思 3.2 代码实例 3.3 运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性&a…

B站启用adblock插件导致无法看到评论

1 进入adblock插件的设置页面 2 进入自定义规则页面&#xff0c;编辑过滤规则 删除掉这一项 www.bilibili.com##P 然后&#xff0c;点击保存&#xff1b; 刷新页面就可以看到B站评论区的评论了。

可以拖拽的富文本编辑器(VueDragResize,quill-editor)

该功能实现一个帮助文档的展示和编辑功能&#xff0c;默认进去只能查看帮助文档的内容&#xff0c;点击编辑可以进行富文本编辑器的编辑功能。 出现的问题1.如何隐藏富文本编辑的工具栏并且禁止编辑 //隐藏工具栏this.toolbar this.$refs.myTextEditor.quill.getModule(toolb…

化妆品3D虚拟三维数字化营销展示更加生动、真实、高效!

随着人们越来越追求高速便捷的生活工作方式&#xff0c;企业在营销市场也偏国际化&#xff0c;借助VR全景制作技术&#xff0c;将企业1:1复刻到云端数字化世界&#xff0c;能带来高沉浸式的逼真、震撼效果。 通过我们独特的漫游点自然场景过渡技术&#xff0c;您将置身于一个真…

开发个人Go-ChatGPT--5 模型管理 (一)

开发个人Go-ChatGPT–5 模型管理 (一) 背景 开发一个chatGPT的网站&#xff0c;后端服务如何实现与大模型的对话&#xff1f;是整个项目中开发困难较大的点。 如何实现上图的聊天对话功能&#xff1f;在开发后端的时候&#xff0c;如何实现stream的响应呢&#xff1f;本文就…

JRE、JVM、JDK分别是什么。

JDK JDK的英文全称是Java Development Kit。JDK是用于制作程序和Java应用程序的软件开发环境。JDK 是 Java 开发工具包&#xff0c;它是 Java 开发者用来编写、编译、调试和运行 Java 程序的集合。JDK 包括了 Java 编译器&#xff08;javac&#xff09;、Java 运行时环境&…

SLAM相关知识

目前在SLAM上的传感器主要分为两大类&#xff1a;激光雷达和摄像头 激光雷达&#xff1a;单线、多线 摄像头&#xff1a;单目相机&#xff08;普通USB相机&#xff09;、双目相机&#xff08;2个普通的USB相机&#xff09;、单目结构光&#xff08;深度相机&#xff09;、双目…

编辑器 goland 和 visual studio code

goland 编辑器做的真是太好了&#xff0c;面向 go 代码的定制设计&#xff0c;但它是收费软件&#xff0c;价格还贵的超出了自己的经济能力范围。有时候想打几行代码&#xff0c;却没有趁手的兵器&#xff0c;真是难受。但求助免费破解版吧&#xff0c;又需要关注公众号&#x…

用流式数据库解决「自动化检测服务器性能异常」难题

对 DevOps 团队来说&#xff0c;检测大量服务器的性能异常并尽快响应一直是个挑战。他们设置了各种指标来监控服务器性能&#xff0c;但诊断性能问题复杂且耗时&#xff0c;因为诊断数据的量可能非常大。越来越多的人认为这个过程应该自动化。但怎么做呢&#xff1f; 流式系统…