使用Fastify和PostgreSQL构建Didit Webhook监听器 (ZH)
学习如何使用Node.js、Fastify和PostgreSQL为Didit的实时身份验证通知构建一个健壮且安全的Webhook监听器。.

安全Webhook集成实施HMAC-SHA256签名验证对于确保Didit Webhook有效载荷的真实性和完整性至关重要,保护您的应用程序免受伪造请求的侵害并维护数据安全。
实时数据处理利用Webhooks接收身份验证会话状态变化的即时通知,使您的应用程序能够立即作出反应,并自动化用户入职或风险管理工作流程。
可扩展数据存储利用PostgreSQL高效存储和管理Webhook数据,实现强大的查询、审计以及与现有用户管理系统的集成,确保数据持久性和可靠性。
Didit的模块化优势Didit的模块化身份平台和全面的Webhook系统简化了集成,为开发人员提供了清晰的API和实时数据流,以构建灵活的、AI原生的KYC解决方案,提供免费核心KYC且无设置费用。
理解Didit Webhooks及其重要性
在身份验证领域,实时反馈至关重要。无论是新用户入职、防范欺诈还是确保合规性,实时了解验证会话的状态都至关重要。这就是Webhooks的作用。Didit的Webhooks提供了一种自动化的方式,可以接收关于身份验证工作流程中发生的事件的通知,例如会话完成、失败或需要进一步操作。
Didit的Webhooks不会不断轮询Didit API以获取更新(这可能效率低下并导致延迟),而是将数据直接推送到您配置的端点。这种事件驱动的架构确保您的应用程序始终拥有最新信息,从而实现即时处理和更流畅的用户体验。例如,一旦用户成功完成Didit的身份验证和被动与主动活体检测,Webhook可以立即触发您的入职流程的下一步。
Didit提供可配置的Webhook版本,v3是推荐的标准,因为它具有全面的有效载荷结构。您可以直接通过Didit业务控制台或通过API设置您的Webhook URL、版本,甚至定义数据保留策略,从而完全控制您的数据流和合规性义务。
设置您的Fastify Webhook监听器
Fastify是一个用于Node.js的快速且低开销的Web框架,是构建高性能Webhook监听器的绝佳选择。以下是入门方法:
1. 项目设置和依赖项
首先,初始化您的Node.js项目并安装必要的软件包:
mkdir didit-webhook-listener
cd didit-webhook-listener
npm init -y
npm install fastify dotenv pg crypto
创建一个.env文件来存储您的Didit Webhook密钥和PostgreSQL连接详细信息:
DIDIT_WEBHOOK_SECRET=your_didit_webhook_secret_key
DATABASE_URL=postgresql://user:password@host:port/database
您可以从Didit业务控制台的“应用设置”中或通过Didit API的GET /v3/webhook/端点检索您的DIDIT_WEBHOOK_SECRET。
2. Fastify服务器配置
创建一个app.js文件。Fastify需要原始正文进行签名验证,因此我们将配置它,使其不对我们的Webhook路由自动解析JSON。
require('dotenv').config();
const fastify = require('fastify')({ logger: true });
const crypto = require('crypto');
const { Client } = require('pg');
const DIDIT_WEBHOOK_SECRET = process.env.DIDIT_WEBHOOK_SECRET;
const DATABASE_URL = process.env.DATABASE_URL;
const pgClient = new Client({ connectionString: DATABASE_URL });
// 为'application/json'注册一个内容解析器,它为特定路由保留原始正文
fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, function (req, body, done) {
if (req.raw.url === '/webhooks/didit') {
done(null, body); // 为webhook端点保留原始数据
} else {
try {
const json = JSON.parse(body.toString());
done(null, json);
} catch (error) {
error.statusCode = 400;
done(error, undefined);
}
}
});
fastify.post('/webhooks/didit', async (request, reply) => {
const signature = request.headers['x-signature'];
const timestamp = request.headers['x-timestamp'];
const rawBody = request.body;
if (!signature || !timestamp || !rawBody) {
reply.code(400).send({ message: '缺少签名、时间戳或正文' });
return;
}
// 1. 验证HMAC-SHA256签名
const expectedSignature = crypto
.createHmac('sha256', DIDIT_WEBHOOK_SECRET)
.update(`${timestamp}.${rawBody.toString()}`)
.digest('hex');
if (expectedSignature !== signature) {
reply.code(403).send({ message: '无效签名' });
return;
}
// 2. 验证时间戳(例如,在5分钟内以防止重放攻击)
const fiveMinutesAgo = Date.now() - (5 * 60 * 1000);
if (parseInt(timestamp) < fiveMinutesAgo) {
reply.code(403).send({ message: '时间戳过旧' });
return;
}
// 3. 验证后解析JSON正文
let payload;
try {
payload = JSON.parse(rawBody.toString());
} catch (error) {
reply.code(400).send({ message: '无效的JSON有效载荷' });
return;
}
fastify.log.info('收到Didit webhook:', payload);
// 4. 处理webhook有效载荷(例如,存储到数据库,更新用户状态)
try {
await pgClient.query(
'INSERT INTO webhooks (event_id, event_type, payload, received_at) VALUES ($1, $2, $3, NOW())',
[payload.id, payload.event, JSON.stringify(payload)]
);
// 示例:根据payload.status更新用户状态
// await pgClient.query(
// 'UPDATE users SET verification_status = $1 WHERE didit_session_id = $2',
// [payload.status, payload.session_id]
// );
reply.code(200).send({ message: 'Webhook已接收并处理' });
} catch (dbError) {
fastify.log.error('数据库错误:', dbError);
reply.code(500).send({ message: '内部服务器错误' });
}
});
const start = async () => {
try {
await pgClient.connect();
fastify.log.info('已连接到PostgreSQL');
await fastify.listen({ port: 3000, host: '0.0.0.0' });
} catch (err) {
fastify.log.error(err);
process.exit(1);
}
};
start();
将Webhook数据存储在PostgreSQL中
持久化Webhook数据对于审计、调试和确保数据完整性至关重要。PostgreSQL是一个健壮的关系型数据库,非常适合此任务。
1. 数据库模式
首先,创建一个表来存储您的Webhook事件。此模式提供了一个很好的起点:
CREATE TABLE webhooks (
id SERIAL PRIMARY KEY,
event_id VARCHAR(255) UNIQUE NOT NULL, -- Didit的唯一事件ID
event_type VARCHAR(255) NOT NULL,
payload JSONB NOT NULL, -- 存储完整的JSON有效载荷
received_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
2. 与Fastify集成
如app.js示例所示,我们集成了pg客户端以连接到您的PostgreSQL数据库并插入传入的Webhook有效载荷。payload JSONB NOT NULL列非常适合存储整个JSON对象,允许以后进行灵活查询,而无需为Didit可能引入的每个新字段更改预定义模式。
请记住优雅地处理潜在的数据库错误。上面的示例包含一个用于数据库操作的基本try-catch块。
保护您的Webhook端点
在处理敏感身份验证数据时,安全性至关重要。Didit使用HMAC-SHA256签名来确保传入的Webhooks是合法的且未被篡改。
1. HMAC签名验证
每个Didit Webhook请求都包含两个关键的标头:X-Signature和X-Timestamp。X-Signature标头包含使用您的唯一Webhook密钥和与时间戳连接的原始请求正文生成的HMAC-SHA256签名。您的监听器必须:
- 检索您的
DIDIT_WEBHOOK_SECRET。 - 提取
X-Signature和X-Timestamp标头。 - 重建签名有效载荷:
`${timestamp}.${rawBody}`。 - 使用您的密钥和重建的有效载荷生成您自己的HMAC-SHA256签名。
- 将您生成的签名与请求中的
X-Signature进行比较。如果它们不匹配,则拒绝请求。
提供的Fastify示例演示了这一确切过程,确保只处理真实的Didit Webhooks。
2. 时间戳验证
X-Timestamp标头对于防止重放攻击至关重要。当攻击者拦截合法的Webhook并在稍后重新发送时,就会发生重放攻击。通过检查时间戳是否是最近的(例如,在当前时间的5分钟内),您可以减轻这种风险。Fastify代码片段包含一个检查以确保时间戳不过旧。
Didit如何提供帮助
Didit平台旨在使身份验证的集成无缝且安全。我们的模块化架构允许您即插即用各种身份检查,从用于强大文档分析的身份验证到用于高安全性电子护照/电子身份证检查的NFC验证,以及用于合规性的反洗钱筛选与监控。Webhook系统是这种模块化的核心组件,提供实时更新,使您能够协调复杂的KYC工作流程,而无需持续轮询。
Didit的AI原生方法意味着我们的系统不断学习和适应,提供卓越的准确性和欺诈检测。清晰的API文档和开发者优先的理念,结合免费核心KYC和无设置费用等功能,使得入门变得容易。我们的Webhooks提供结构化的身份数据,允许您的应用程序智能地响应验证结果,并在全球范围内大规模自动化信任。无论您是需要使用Didit的年龄估算验证年龄,还是通过被动与主动活体检测确保用户是活生生的人,Didit都提供了强大身份解决方案所需的工具和实时反馈。
准备好开始了吗?
准备好亲身体验Didit了吗?立即获取免费演示。
使用Didit的免费套餐免费开始验证身份。