1. 用 JavaScript 连接数据价值
在 Fintech 产品的快速迭代中,Node.js 凭借其非阻塞 I/O 和极其丰富的 npm 生态,成为构建 BFF (Backend for Frontend) 层或 Serverless 云函数 的首选。
天远风控决策接口 (JRZQ3P01) 1返回的是标准的 JSON 数据,这与 JavaScript 简直是"天作之合"。然而,为了保障金融级数据的安全,该接口引入了 AES-128-CBC 加密机制 2。对于习惯了"一把梭"的 JS 开发者来说,处理二进制 Buffer、IV 向量和 Base64 编码可能会稍显棘手。
本文将演示如何利用 Node.js 原生 crypto 模块(无需安装臃肿的第三方加密库),优雅地完成接口对接,并将复杂的风控数据转化为前端可直接使用的 UI 状态。
2. API 调用实战:原生模块的优雅实现
我们推荐使用 axios 处理网络请求,使用 Node.js 内置的 crypto 处理加密。这种组合既轻量又标准。
2.1 环境准备
Bash
arduino
npm install axios
# crypto 是内置模块,无需安装
2.2 完整代码实现 (支持 Async/Await)
这段代码封装了一个通用的 RiskClient 类,自动处理了 AES 的 PKCS7 填充(Node.js crypto 默认支持)和 Base64 拼接逻辑。
JavaScript
ini
const axios = require('axios');
const crypto = require('crypto');
class TianyuanRiskClient {
constructor(accessId, accessKeyHex) {
this.apiUrl = '<https://api.tianyuanapi.com/api/v1/JRZQ3P01>'; // this.accessId = accessId;
// 将16进制字符串转为 Buffer 对象,这是关键一步
this.accessKey = Buffer.from(accessKeyHex, 'hex'); //
}
/**
* 加密流程:
* 1. 生成随机 IV
* 2. AES-128-CBC 加密 (默认 PKCS7 填充)
* 3. 拼接 IV + 密文 -> Base64
*/
encrypt(data) {
const iv = crypto.randomBytes(16); // const cipher = crypto.createCipheriv('aes-128-cbc', this.accessKey, iv);
// JSON 序列化
const plainText = JSON.stringify(data);
let encrypted = cipher.update(plainText, 'utf8');
encrypted = Buffer.concat([encrypted, cipher.final()]);
// 拼接 IV 和 密文
const combined = Buffer.concat([iv, encrypted]);
// 返回 Base64 字符串 return combined.toString('base64');
}
/**
* 解密流程
*/
decrypt(base64Data) {
const buffer = Buffer.from(base64Data, 'base64');
// 提取前 16 字节作为 IV
const iv = buffer.slice(0, 16); // const text = buffer.slice(16);
const decipher = crypto.createDecipheriv('aes-128-cbc', this.accessKey, iv);
let decrypted = decipher.update(text);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return JSON.parse(decrypted.toString());
}
/**
* 核心调用方法
*/
async queryRisk(name, idCard) {
try {
// 1. 准备并加密数据
const payload = { name, id_card: idCard }; // [cite: 2]
const encryptedData = this.encrypt(payload);
// 2. 发起请求 (注意时间戳参数 t)
const response = await axios.post(
this.apiUrl,
{ data: encryptedData }, // 请求体字段名为 data
{
headers: { 'Access-Id': this.accessId }, // params: { t: Date.now() } // 防止重放攻击
}
);
const resData = response.data;
// 3. 处理响应
if (resData.code === 0) {
// 成功:解密数据
const realData = this.decrypt(resData.data);
console.log('✅ 风控查询成功');
return realData;
} else {
console.error(`❌ API 错误: ${resData.message} (Code: ${resData.code})`); // return null;
}
} catch (error) {
console.error('网络请求异常:', error.message);
return null;
}
}
}
// --- 调用示例 ---
(async () => {
// ⚠️ 生产环境请从 process.env 读取密钥
const client = new TianyuanRiskClient(
'YOUR_ACCESS_ID',
'YOUR_HEX_KEY_STRING'
);
const result = await client.queryRisk('李四', '33010619850101xxxx');
if (result) {
console.log('审核建议:', result.reviewSuggestions); // console.log('详细数据:', result);
}
})();
3. 核心数据结构解析:JS 对象的陷阱与技巧
JavaScript 虽然处理 JSON 方便,但在处理天远 API 返回的数据时,有几个类型陷阱需要全栈开发者特别注意。
3.1 响应字段概览
API 返回的 JSON 结构极其扁平,非常利于解构赋值:
JavaScript
arduino
const {
reviewSuggestions, // 核心建议 A-F
blackOrgNum, // 黑名单机构数,如 ">3"
loanTypes, // 借贷偏好对象
lastCondition // 风险标签对象
} = result;
3.2 这里的 "Boolean" 是字符串!
这是 JS 开发者最容易踩的坑。
在 lastCondition 和 loanTypes 对象中,字段值 1 代表命中,0 代表未命中 3,但它们是 String 类型,不是 Number 或 Boolean。
-
❌ 错误写法:JavaScript
rubyif (result.lastCondition.fraud) { // 危险!因为 "0" (字符串) 在 JS 中也是 true! // 导致系统误判用户有欺诈风险 } -
✅ 正确写法:JavaScript
iniconst isFraud = result.lastCondition.fraud === '1'; // const isSeriousOverdue = result.lastCondition.seriousOverdue === '1';
3.3 关键字段映射表
| 字段名 | JS 类型 | 含义 | 业务逻辑建议 |
|---|---|---|---|
reviewSuggestions |
String | 审核建议 | 前端可映射颜色:A/B -> 红色(拒绝), C/D -> 黄色(警告), E -> 绿色(通过)。4 |
overdueAmt |
String | 逾期金额 | 返回如 >8000。建议正则提取数字 parseInt(val.match(/\d+/)[0]) 用于排序。 |
blackOrgNum |
String | 黑名单数 | 多头借贷的重要指标,值越大风险越高。 |
4. 应用价值:Serverless 与 中间件
在 Node.js 生态中,我们可以将这个 API 玩出花样:
4.1 场景一:构建 Serverless 各种云函数
利用 AWS Lambda 或 腾讯云 SCF,你可以把上面的代码封装成一个微服务。
- 优势 :天远 API 按次计费 (¥2.5/次) 5,配合 Serverless 的按量计费,可以实现零闲置成本的风控服务。只有当用户真正发起贷款申请时,才产生费用。
4.2 场景二:BFF 层的数据清洗 (Data Sanitization)
前端通常不需要知道"Base64"或"加密"细节。Node.js 中间层可以做一次脏活累活:
- 调用天远 API。
- 解密数据。
- 清洗数据 :把
"1"/"0"转为true/false,把reviewSuggestions: "A"转为{ status: "REJECT", message: "严重逾期" }。 - 返回给前端干净的 JSON。
4.3 场景三:异常熔断
使用 Opossum 等熔断库包裹 queryRisk 方法。如果网络波动导致 API 连续超时,Node.js 服务可以自动快速失败 (Fail Fast),返回兜底策略(如转人工审核),而不是让用户一直转圈等待。
总结
Node.js 加上 天远风控 API,是构建轻量级信贷审批系统的黄金搭档。通过 Node.js 原生的加密支持,我们可以快速打通数据链路;而 JavaScript 灵活的对象处理能力,让我们能轻松地将原始风控数据转化为直观的业务洞察。
最后的小贴士:
- 安全:不要把 Access Key 提交到前端代码中!一定要在后端或云函数中调用。
- 成本:接口调用不是免费的 6,在开发调试阶段,建议 Mock 模拟数据,避免产生不必要的费用。