欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Jackson實現(xiàn)API接口數(shù)據(jù)脫敏的示例詳解

 更新時間:2023年08月11日 11:30:51   作者:skywsp  
用戶的一些敏感數(shù)據(jù),例如手機號、郵箱、身份證等信息,在數(shù)據(jù)庫以明文存儲,但在接口返回數(shù)據(jù)給瀏覽器(或三方客戶端)時,希望對這些敏感數(shù)據(jù)進行脫敏,所以本文就給大家介紹以惡如何利用Jackson實現(xiàn)API接口數(shù)據(jù)脫敏,需要的朋友可以參考下

一、背景

用戶的一些敏感數(shù)據(jù),例如手機號、郵箱、身份證等信息,在數(shù)據(jù)庫以明文存儲(加密存儲見《基于Mybatis-Plus攔截器實現(xiàn)MySQL數(shù)據(jù)加解密》), 但在接口返回數(shù)據(jù)給瀏覽器(或三方客戶端)時,希望對這些敏感數(shù)據(jù)進行脫敏。 同時在瀏覽器提交數(shù)據(jù)更新到后端接口時,后端接口需要判斷敏感數(shù)據(jù)是否已脫敏,如果已脫敏則需要直接丟棄。

二、Jackson介紹

Jackson是SpringBoot默認(rèn)的Json序列化和反序列化庫,點擊這里查看Jackson注解官方文檔.

本文通過使用Jackson的@JsonSerialize注解實現(xiàn)序列化時脫敏操作,通過使用Jackson的@JsonDeserialize注解實現(xiàn)反序列化時脫敏數(shù)據(jù)檢測并丟棄操作。

三、使用方法

該脫敏攔截器功能在wutong-base-api包(公司內(nèi)部包)已經(jīng)實現(xiàn),如果您的項目已經(jīng)依賴了base-api,就可以直接使用。

另外,在碼云上有Demo案例,見: spring-jackson

基于wutong-base-api包的使用步驟如下。

1、添加wutong-base-api依賴

<dependency>
    <groupId>com.talkweb</groupId>
    <artifactId>wutong-base-api</artifactId>
    <version>請使用最新版本</version>
</dependency>

2、在yaml配置開關(guān),啟用加解密

spring:
  jackson:
    sensitive:
      # 序列化時是否對手機號進行脫敏,反序列化時是否過濾脫敏數(shù)據(jù)
      mobile: true
      # 序列化時是否對郵箱進行脫敏,反序列化時是否過濾脫敏數(shù)據(jù)
      email: true
      # 序列化時是否對身份證號進行脫敏,反序列化時是否過濾脫敏數(shù)據(jù)
      identity: true

3、定義VO類,使用Jackson注解實現(xiàn)數(shù)據(jù)脫敏

API接口出參(Rsp),敏感數(shù)據(jù)序列化時脫敏

public class UserRspVO {
    private Long id;
    private String name;
    @JsonSerialize(using = CustomerJackSon.MobileSerialize.class)
    private String mobile;
    @JsonSerialize(using = CustomerJackSon.EmailSerialize.class)
    private String email;
    @JsonSerialize(using = CustomerJackSon.IdentitySerialize.class)
    private String identity;
}

API接口入?yún)?Req),過濾已脫敏的數(shù)據(jù),直接丟棄

public class UserReqVO {
    private Long id;
    private String name;
    @JsonDeserialize(using = CustomerJackSon.MobileDeSerialize.class)
    private String mobile;
    @JsonDeserialize(using = CustomerJackSon.EmailDeSerialize.class)
    private String email;
    @JsonDeserialize(using = CustomerJackSon.IdentityDeSerialize.class)
    private String identity;
}

定義Controller接口

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping
    public UserRspVO get() {
        UserRspVO rsp = new UserRspVO();
        rsp.setId(1L);
        rsp.setName("張三");
        rsp.setMobile("18866661234");
        rsp.setEmail("zhangsan@qq.com");
        rsp.setIdentity("434113199901015566");
        return rsp;
    }
    @PutMapping
    public UserRspVO put(@RequestBody UserReqVO req) {
        System.out.println(req);
        UserRspVO rsp = new UserRspVO();
        BeanUtils.copyProperties(req, rsp);
        return rsp;
    }
}

接口請求示例:

GET http://localhost:8080/user
入?yún)ⅲ?
無
出參:
{
  "id": "1",
  "name": "張三",
  "mobile": "188****1234", // 配置了mobile=true
  "email": "zhangsan@qq.com", // 配置了email=false
  "identity": "434113199901015566" // 未配置identity,默認(rèn)為false
}
PUT http://127.0.0.1:8080/user
入?yún)ⅲ?
{
    "id": "12124",
    "name": "張三",
    "mobile": "188****1234",
    "email": "zh****@qq.com",
    "identity": "434***********5566"
}
Controller反序列化后接收到的數(shù)據(jù):
{
    "id": "12124",
    "name": "張三",
    "mobile": null, // 配置了mobile=true
    "email": "zh****@qq.com", // 配置了email=false
    "identity": "434***********5566" // 未配置identity,默認(rèn)為false
}

四、實現(xiàn)原理

1、SpringBoot定義變量實現(xiàn)脫敏開關(guān)

讀取yaml配置

@ConfigurationProperties(prefix = "spring.jackson.sensitive")
public class JacksonProperties {
    private Boolean mobile;
    private Boolean email;
    private Boolean identity;
}

變量注入到JacksonConfig

@Configuration
@EnableConfigurationProperties(JacksonProperties.class)
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper(JacksonProperties props) {
        ObjectMapper mapper = new ObjectMapper();
        ContextAttributes attrs = ContextAttributes.getEmpty()
                .withSharedAttribute("mobile", props.getMobile())
                .withSharedAttribute("email", props.getEmail())
                .withSharedAttribute("identity", props.getIdentity());
        mapper.setDefaultAttributes(attrs);
        return mapper;
    }
}

2、實現(xiàn)序列化、反序列化邏輯

public class CustomerJackSon {
    /**
     * 手機號脫敏序列化
     */
    public static class MobileSerialize extends JsonSerializer<String> {
        @Override
        public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (null == value || value.length() != 11) {
                jsonGenerator.writeString(value);
                return;
            }
            Boolean mobile = (Boolean) serializerProvider.getAttribute("mobile");
            if (null == mobile || !mobile) {
                jsonGenerator.writeString(value);
                return;
            }
            jsonGenerator.writeString(value.substring(0, 3) + "****" + value.substring(7));
        }
    }
    /**
     * 手機號脫敏數(shù)據(jù)檢測并丟棄
     */
    public static class MobileDeSerialize extends JsonDeserializer<String> {
        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
            String value = p.getText();
            if (null == value || value.length() != 11) {
                return value;
            }
            Boolean mobile = (Boolean) ctxt.getAttribute("mobile");
            if (null == mobile || !mobile) {
                return value;
            }
            if (value.contains("*")) {
                return null;
            }
            return value;
        }
    }
    /**
     * 郵箱脫敏序列化
     */
    public static class EmailSerialize extends JsonSerializer<String> {
        @Override
        public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (null == value || value.length() < 5) {
                jsonGenerator.writeString(value);
                return;
            }
            String[] split = value.split("@");
            if (split.length != 2 || split[0].length() < 2 || split[1].length() < 2) {
                jsonGenerator.writeString(value);
                return;
            }
            Boolean email = (Boolean) serializerProvider.getAttribute("email");
            if (null == email || !email) {
                jsonGenerator.writeString(value);
                return;
            }
            jsonGenerator.writeString(split[0].substring(0, 2) + "****@" + split[1]);
        }
    }
    /**
     * 郵箱脫敏數(shù)據(jù)檢測并丟棄
     */
    public static class EmailDeSerialize extends JsonDeserializer<String> {
        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
            String value = p.getText();
            if (null == value || value.length() < 5) {
                return value;
            }
            Boolean email = (Boolean) ctxt.getAttribute("email");
            if (null == email || !email) {
                return value;
            }
            if (value.contains("*")) {
                return null;
            }
            return value;
        }
    }
    /**
     * 身份證脫敏序列化
     */
    public static class IdentitySerialize extends JsonSerializer<String> {
        @Override
        public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (null == value || value.length() != 18) {
                jsonGenerator.writeString(value);
                return;
            }
            Boolean identity = (Boolean) serializerProvider.getAttribute("identity");
            if (null == identity || !identity) {
                jsonGenerator.writeString(value);
                return;
            }
            jsonGenerator.writeString(value.substring(0, 3) + "***********" + value.substring(14));
        }
    }
    /**
     * 身份證脫敏數(shù)據(jù)檢測并丟棄
     */
    public static class IdentityDeSerialize extends JsonDeserializer<String> {
        @Override
        public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
            String value = p.getText();
            if (null == value || value.length() != 18) {
                return value;
            }
            Boolean identity = (Boolean) ctxt.getAttribute("identity");
            if (null == identity || !identity) {
                return value;
            }
            if (value.contains("*")) {
                return null;
            }
            return value;
        }
    }
}

以上就是基于Jackson實現(xiàn)API接口數(shù)據(jù)脫敏的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Jackson API接口數(shù)據(jù)脫敏的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • FreeMarker配置(Configuration)

    FreeMarker配置(Configuration)

    所有與該configuration 對象關(guān)聯(lián)的模版實例都就可以通過獲得to_upper 轉(zhuǎn)換器,company 來獲得字符串,因此你不需要再一次次的往root 中添加這些變量了。如果你往root 添加同名的變量,那么你新添加的變量將會覆蓋之前的共享變量。
    2016-04-04
  • Java參數(shù)按值傳遞示例演示

    Java參數(shù)按值傳遞示例演示

    在Java中,方法參數(shù)的傳遞方式實際上是按值傳遞,接下來通過本文給大家介紹了Java參數(shù)按值傳遞示例演示,需要的朋友可以參考下
    2023-09-09
  • 【spring-boot】快速構(gòu)建spring-boot微框架的方法

    【spring-boot】快速構(gòu)建spring-boot微框架的方法

    本篇文章主要介紹了【spring-boot】快速構(gòu)建spring-boot微框架的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • SpringBoot集成Curator實現(xiàn)Zookeeper基本操作的代碼示例

    SpringBoot集成Curator實現(xiàn)Zookeeper基本操作的代碼示例

    Zookeeper是一個Apache開源的分布式的應(yīng)用,為系統(tǒng)架構(gòu)提供協(xié)調(diào)服務(wù),ZooKeeper的目標(biāo)就是封裝好復(fù)雜易出錯的關(guān)鍵服務(wù),將簡單易用的接口和性能高效、功能穩(wěn)定的系統(tǒng)提供給用戶,本文給大家介紹了SpringBoot集成Curator實現(xiàn)Zookeeper基本操作,需要的朋友可以參考下
    2024-05-05
  • Java軟件編程培訓(xùn)機構(gòu)靠譜嗎

    Java軟件編程培訓(xùn)機構(gòu)靠譜嗎

    隨著網(wǎng)絡(luò)信息化的快速發(fā)展,Java培訓(xùn)受到越來越多人的青睞,目前Java工程師的薪資水平在不斷攀升,但是有好多企業(yè)還是招不到合適的人才,為什么呢
    2017-04-04
  • SpringBoot3整合WebSocket詳細(xì)指南

    SpringBoot3整合WebSocket詳細(xì)指南

    SpringBoot 3 整合 WebSocket 提供了一種高效的實時通信解決方案,通過本文的配置和示例,可以快速實現(xiàn),感興趣的哦朋友跟隨小編一起看看吧
    2024-12-12
  • Java入門案列之猜拳小游戲

    Java入門案列之猜拳小游戲

    這篇文章主要為大家詳細(xì)介紹了Java入門案列之猜拳小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 在navicat中導(dǎo)入mysql數(shù)據(jù)庫詳細(xì)步驟(即.sql后綴的數(shù)據(jù)庫)

    在navicat中導(dǎo)入mysql數(shù)據(jù)庫詳細(xì)步驟(即.sql后綴的數(shù)據(jù)庫)

    Navicat是MySQL非常好用的可視化管理工具,功能非常強大,能滿足我們?nèi)粘?shù)據(jù)庫開發(fā)的所有需求,下面這篇文章主要給大家介紹了關(guān)于如何在navicat中導(dǎo)入mysql數(shù)據(jù)庫(即.sql后綴的數(shù)據(jù)庫)的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • windows下java環(huán)境變量的設(shè)置方法

    windows下java環(huán)境變量的設(shè)置方法

    在“系統(tǒng)變量”中,設(shè)置3項屬性,JAVA_HOME,PATH,CLASSPATH(大小寫無所謂),若已存在則點擊“編輯”,不存在則點擊“新建”
    2013-09-09
  • Java8如何利用Lambda快速生成map、多層嵌套map

    Java8如何利用Lambda快速生成map、多層嵌套map

    這篇文章主要介紹了Java8如何利用Lambda快速生成map、多層嵌套map問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評論