4. 反欺诈评分接口设计:接口架构设计、请求与响应规范、接口安全策略
反欺诈评分接口是风控系统的核心对外服务层,承担着实时接收业务请求、调用决策引擎、返回风险评分与标签的关键职责。本章从接口架构、请求/响应规范、安全策略三个维度,讲解如何设计一个高可用、低延迟、防篡改的反欺诈评分接口。
4.1 接口架构设计
反欺诈评分接口采用分层解耦架构,分为接入层、服务层、决策层与存储层。各层职责清晰,便于水平扩展与独立运维。
架构设计原则:
- 无状态化:接口层不保存业务上下文,便于横向扩缩容。
- 异步化:非核心逻辑(如日志、异步标签计算)通过消息队列解耦。
- 熔断降级:依赖的第三方服务(如设备指纹、黑名单库)异常时自动降级。
4.2 请求与响应规范
接口采用 RESTful 风格,统一使用 JSON 格式进行数据交换。请求与响应结构需兼顾可读性与传输效率,同时预留扩展字段。
4.2.1 请求结构
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| request_id | String | 是 | 全局唯一请求ID,用于链路追踪与去重 |
| timestamp | Long | 是 | 请求发起时间戳(毫秒),用于防重放 |
| partner_code | String | 是 | 合作方标识,用于路由与鉴权 |
| event_type | String | 是 | 事件类型:login / register / payment / withdraw |
| user_id | String | 是 | 用户唯一标识(手机号/UID) |
| device_id | String | 否 | 设备指纹ID |
| ip | String | 否 | 客户端IP地址 |
| extra | JSON | 否 | 扩展字段,用于传递业务自定义参数 |
| sign | String | 是 | 请求签名,用于防篡改 |
// 请求示例
{
"request_id": "202503211234567890123456",
"timestamp": 1742550000000,
"partner_code": "partner_001",
"event_type": "login",
"user_id": "13800138000",
"device_id": "DFA8E2C1-9B3F-4A7D-8E5F-2C1B3A4D5E6F",
"ip": "192.168.1.100",
"extra": {
"login_channel": "app",
"login_type": "password"
},
"sign": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
}
4.2.2 响应结构
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | Integer | 是 | 业务状态码:0 成功,非0 异常 |
| message | String | 是 | 状态描述信息 |
| request_id | String | 是 | 回传请求ID,用于问题排查 |
| data | JSON | 否 | 评分结果数据体 |
| data.score | Integer | 是 | 反欺诈评分(0-100,越高风险越大) |
| data.level | String | 是 | 风险等级:low / medium / high / critical |
| data.tags | Array | 否 | 风险标签列表,如 ["device_anomaly", "ip_proxy"] |
| data.hit_rules | Array | 否 | 命中规则ID列表 |
| data.extra | JSON | 否 | 扩展信息,如团伙ID、关联设备数 |
// 响应示例
{
"code": 0,
"message": "success",
"request_id": "202503211234567890123456",
"data": {
"score": 85,
"level": "high",
"tags": ["device_anomaly", "ip_proxy", "multi_account"],
"hit_rules": ["R1001", "R2034", "R3078"],
"extra": {
"gang_id": "gang_0042",
"related_devices": 12,
"related_accounts": 8
}
}
}
设计要点:
- 响应中回传
request_id,便于调用方与服务端对齐日志。 - 评分与风险等级同时返回,调用方可按等级直接决策,也可按评分自定义阈值。
- 扩展字段
extra用于传递团伙识别等高级分析结果,避免频繁修改接口结构。
4.3 接口安全策略
反欺诈评分接口直接暴露在业务调用链中,必须防范重放攻击、参数篡改、越权调用等安全风险。以下为必须实施的安全策略。
4.3.1 签名机制
采用 HMAC-SHA256 对请求参数进行签名,服务端验签后处理。签名算法如下:
- 将请求参数按字典序排序(排除 sign 字段)。
- 拼接为 key=value 格式,用 & 连接。
- 拼接密钥(合作方分配)后,计算 HMAC-SHA256 值。
- 将结果转为小写十六进制字符串,放入 sign 字段。
// 签名生成示例(Java)
public static String generateSign(Map<String, String> params, String secret) {
// 1. 排序
TreeMap<String, String> sorted = new TreeMap<>(params);
sorted.remove("sign");
// 2. 拼接
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : sorted.entrySet()) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
sb.deleteCharAt(sb.length() - 1);
// 3. HMAC-SHA256
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(keySpec);
byte[] hash = mac.doFinal(sb.toString().getBytes(StandardCharsets.UTF_8));
// 4. 转十六进制
return bytesToHex(hash).toLowerCase();
}
4.3.2 防重放攻击
利用 timestamp 与 request_id 双重机制防止重放:
- 时间窗口校验:服务端校验请求时间戳与当前时间差是否在 ±5 分钟内,超出则拒绝。
- 请求ID去重:Redis 缓存已处理的
request_id,设置 TTL 为 10 分钟,重复请求直接返回上次结果或拒绝。
4.3.3 访问控制与限流
| 策略 | 实现方式 | 说明 |
|---|---|---|
| IP白名单 | API Gateway 层配置 | 仅允许合作方固定出口IP调用 |
| API Key 鉴权 | Header 中携带 X-Api-Key | 配合签名使用,标识调用方身份 |
| 令牌桶限流 | Redis + Lua 脚本 | 按合作方+接口维度限流,QPS 超限返回 429 |
| 参数校验 | 服务层前置校验 | 字段类型、长度、枚举值校验,防止注入 |
安全红线:
- 禁止在响应中返回服务端异常堆栈或数据库错误信息。
- 签名密钥必须定期轮换,且不在日志中明文打印。
- 敏感字段(如手机号、身份证)在日志中脱敏处理。
4.4 接口性能与可用性保障
反欺诈评分接口通常要求 P99 延迟在 200ms 以内,可用性不低于 99.95%。以下为关键保障措施:
- 多级缓存:本地缓存(Caffeine)+ 分布式缓存(Redis)缓存高频特征与规则结果。
- 异步日志:请求日志通过 Kafka 异步写入,不阻塞主流程。
- 熔断降级:依赖的第三方服务(如设备指纹、黑名单库)异常时,返回降级评分或默认风险等级。
- 灰度发布:新规则或模型上线时,先灰度 5% 流量,观察指标后再全量。
接口设计检查清单:
- ✅ 请求与响应结构是否包含 request_id 用于链路追踪?
- ✅ 签名机制是否覆盖所有请求参数?
- ✅ 是否实现了时间窗口 + 请求ID去重的防重放策略?
- ✅ 限流策略是否按合作方+接口维度独立配置?
- ✅ 敏感字段是否在日志中脱敏?
- ✅ 是否预留了扩展字段(extra)避免频繁接口升级?