后端用户信息接口脱敏方案

浅谈Java后端用户信息接口脱敏

在开发中,接口往往会返回用户的敏感信息,比如手机号、身份证号、邮箱等。为了保护用户隐私、降低安全风险、并满足法律合规要求,我们需要对这些数据进行脱敏处理

本文基于 Spring Boot 和 Jackson 提供一种灵活的注解式脱敏方案,并结合 Hutool 工具类 DesensitizedUtil 做扩展与优化。

什么是接口数据脱敏?

接口数据脱敏,是指在对外提供 API 时,对返回数据中的敏感信息进行隐藏或模糊处理,常见包括:

为什么要做脱敏?


项目环境

Maven 依赖

1
2
3
4
5
6
7
8
9
10
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>

🛠 实现步骤

1. 定义注解 @Sensitive

1
2
3
4
5
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Sensitive {
SensitiveType type();
}

2. 定义脱敏类型枚举

1
2
3
4
5
public enum SensitiveType {
MOBILE,
ID_CARD,
EMAIL
}

3. 自定义序列化器 SensitiveSerializer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SensitiveSerializer extends JsonSerializer<String> {
private final SensitiveType type;

public SensitiveSerializer(SensitiveType type) {
this.type = type;
}

@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
switch (type) {
case MOBILE:
gen.writeString(value.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
break;
case ID_CARD:
gen.writeString(value.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1******$2"));
break;
case EMAIL:
gen.writeString(value.replaceAll("(^[^@]{3})[^@]*(@.*$)", "$1****$2"));
break;
default:
gen.writeString(value);
}
}
}

实战测试

User 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class User {
private String name;

@Sensitive(type = SensitiveType.MOBILE)
@JsonSerialize(using = SensitiveSerializer.class)
private String mobile;

@Sensitive(type = SensitiveType.ID_CARD)
@JsonSerialize(using = SensitiveSerializer.class)
private String idCard;

@Sensitive(type = SensitiveType.EMAIL)
@JsonSerialize(using = SensitiveSerializer.class)
private String email;

// getters and setters
}

Controller 实战

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
public class UserController {
@GetMapping("/user")
public User getUser() {
User user = new User();
user.setName("张三");
user.setMobile("13812345678");
user.setIdCard("123456789012345678");
user.setEmail("example@example.com");
return user;
}
}

接口输出结果

1
2
3
4
5
6
{
"name": "张三",
"mobile": "138****5678",
"idCard": "1234******5678",
"email": "exa****@example.com"
}

扩展思路:结合 Hutool 的 DesensitizedUtil 使用

Hutool 是一个非常实用的 Java 工具类库,其中 cn.hutool.core.util.DesensitizedUtil 提供了多种类型的脱敏方法,支持手机号、身份证号、邮箱、地址、银行卡号等。

示例用法

1
2
3
4
5
6
7
8
DesensitizedUtil.mobilePhone("13812345678") 
// 输出:138****5678

DesensitizedUtil.idCardNum("123456789012345678", 4, 4)
// 输出:1234********5678

DesensitizedUtil.email("example@example.com")
// 输出:e****@example.com

结合使用

可以在 SensitiveSerializer 中调用 Hutool 提供的方法,替代正则逻辑,代码更简洁、可读性更高:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
String desensitized;
switch (type) {
case MOBILE:
desensitized = DesensitizedUtil.mobilePhone(value);
break;
case ID_CARD:
desensitized = DesensitizedUtil.idCardNum(value, 4, 4);
break;
case EMAIL:
desensitized = DesensitizedUtil.email(value);
break;
default:
desensitized = value;
}
gen.writeString(desensitized);
}

💡 Tips:生产环境可结合 AOP、全局 ObjectMapper 或 ResponseBodyAdvice 进一步封装为全局脱敏处理策略。

About this Post

This post is written by Rui Xu, licensed under CC BY-NC 4.0.

#Java