Xây dựng một Cổng Webhook Mở: Lý do và Cách thức thực hiện
Webhook thường không đáng tin cậy, gây mất dữ liệu và rủi ro bảo mật. Bài viết giới thiệu UpSec, một cổng webhook mở giúp giải quyết các vấn đề về xác minh, thử lại tự động và ghi nhật ký, đảm bảo tính toàn vẹn cho ứng dụng của bạn.

Mọi ứng dụng tôi xây dựng trong vài năm qua đều gặp phải một vấn đề giống nhau: webhook không đáng tin cậy.
Stripe gửi một sự kiện thanh toán, nhưng máy chủ của tôi đang khởi động lại. GitHub gửi thông báo đẩy (push notification), nhưng điểm cuối (endpoint) của tôi trả về lỗi 500. Shopify kích hoạt một đơn hàng webhook, nhưng tôi không biết liệu nó đã thực sự đến hay chưa.
Có vẻ quen thuộc chứ?
Tôi đã cảm thấy mệt mỏi vì phải xây dựng lại logic thử lại (retry logic), xác minh chữ ký và cơ sở hạ tầng ghi nhật ký cho mọi dự án. Vì vậy, tôi đã xây dựng UpSec — một cổng webhook nằm giữa các nhà cung cấp dịch vụ và ứng dụng của bạn.
Vấn đề của Webhook thô (Raw Webhooks)
Webhook hoạt động theo cơ chế "gửi và quên" (fire-and-forget). Người gửi thực hiện một yêu cầu HTTP và chuyển tiếp. Nếu máy chủ của bạn bị sập, quá tải hoặc trả về lỗi — dữ liệu đó sẽ biến mất vĩnh viễn.
Dưới đây là ba rủi ro nghiêm trọng:
- Mất dữ liệu: Máy chủ của bạn ngoại tuyến trong 30 giây khi triển khai (deploy). Một sự kiện
payment_intent.succeededtừ Stripe được kích hoạt. Bạn không bao giờ nhận được nó. Khách hàng đã thanh toán, nhưng hệ thống của bạn không hề biết. - Bảo mật: Bất kỳ ai cũng có thể POST đến URL webhook của bạn. Nếu không có xác minh chữ ký HMAC, bạn đang chấp nhận dữ liệu chưa được xác minh vào hệ thống. Đó là một vectơ tiêm mã độc (injection) đang chờ xảy ra.
- Thiếu khả năng quan sát: Khi có sự cố xảy ra, bạn đang sửa lỗi trong bóng tối. Không có nhật ký (logs). Không có khả năng phát lại (replay). Không có cách nào để xem những gì đã được gửi, khi nào, hoặc liệu nó có được xử lý hay không.
UpSec làm gì?
UpSec là một cổng webhook — một lớp được quản lý nằm giữa các nhà cung cấp webhook và backend của bạn. Thay vì trỏ Stripe trực tiếp đến your-api.com/webhooks/stripe, bạn trỏ nó đến UpSec.
Dưới đây là quy trình hoạt động:
Nhà cung cấp (Stripe, GitHub, v.v.) ↓ UpSec nhận webhook ↓ Xác minh chữ ký HMAC (SHA-256 / SHA-512) ↓ Ghi nhật ký sự kiện với toàn bộ dữ liệu (payload) ↓ Chuyển tiếp đến đích của bạn ↓ Nếu thất bại → Tự động thử lại với cơ chế lùi theo cấp số nhân (30s → 2ph → 10ph → 1giờ)
Tính năng chính
- Endpoint tức thì: Tạo URL webhook trong vài giây. Không cần cài đặt máy chủ.
- Xác minh chữ ký HMAC: Xác minh an toàn về thời gian (timing-safe) cho SHA-256, SHA-512 và các định dạng cụ thể của nhà cung cấp (Stripe, GitHub, Shopify).
- Chuyển tiếp đa đích: Định tuyến một webhook duy nhất đến nhiều dịch vụ nội bộ.
- Tự động thử lại: Lùi theo cấp số nhân với 4 lần thử lại. Không còn sự kiện nào bị mất.
- Nhật ký sự kiện thời gian thực: Xem mọi webhook khi nó đến, bao gồm dữ liệu, tiêu đề và trạng thái chuyển giao.
- Chuyển đổi Payload: Chuyển đổi dữ liệu webhook trước khi chuyển tiếp bằng các quy tắc JSONPath.
Ngăn công nghệ sử dụng
Tôi đã xây dựng UpSec với tập trung vào tốc độ và độ tin cậy:
- Frontend: React + TypeScript + Tailwind CSS
- Backend: Các hàm Edge không máy chủ (Serverless edge functions)
- Cơ sở dữ liệu: PostgreSQL với JSONB để lưu trữ dữ liệu linh hoạt
- Xác minh: So sánh HMAC an toàn về thời gian để ngăn chặn các cuộc tấn công kênh phụ (side-channel attacks)
- SDKs: Node.js, Python và Go
Tích hợp SDK
UpSec cung cấp các SDK để bạn có thể xác minh webhook trong cơ sở mã của riêng mình:
Node.js
npm install @upsec/webhook
import { UpSec } from '@upsec/webhook';
const upsec = new UpSec({ secret: process.env.WEBHOOK_SECRET });
app.post('/webhooks', (req, res) => {
const isValid = upsec.verify(req.body, req.headers['x-webhook-signature']);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Xử lý webhook đã xác minh
handleEvent(req.body);
res.status(200).json({ received: true });
});
Python
pip install upsec-webhook
from upsec import UpSec
upsec = UpSec(secret=os.environ["WEBHOOK_SECRET"])
@app.route("/webhooks", methods=["POST"])
def handle_webhook():
if not upsec.verify(request.data, request.headers.get("x-webhook-signature")):
abort(401)
process_event(request.json)
return jsonify(received=True)
Go
import "github.com/upsec/webhook-go"
func webhookHandler(w http.ResponseWriter, r *http.Request) {
client := upsec.New(os.Getenv("WEBHOOK_SECRET"))
body, _ := io.ReadAll(r.Body)
sig := r.Header.Get("X-Webhook-Signature")
if !client.Verify(body, sig) {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
// Xử lý webhook đã xác minh
}
Tại sao không tự xây dựng?
Bạn hoàn toàn có thể tự làm. Tôi đã làm vậy — nhiều lần. Đó chính là lý do tôi xây dựng UpSec.
Dưới đây là những gì "tự xây dựng" thực sự nghĩa là:
- Xác minh chữ ký: Nghiên cứu định dạng của từng nhà cung cấp, triển khai so sánh an toàn về thời gian. ✅ (UpSec có sẵn)
- Logic thử lại: Xây dựng hàng đợi công việc, triển khai cơ chế lùi, xử lý thư từ chết (dead letters). ✅ (Tự động)
- Ghi nhật ký: Thiết lập ghi nhật ký có cấu trúc, xây dựng giao diện người dùng xem. ✅ (Bảng điều khiển thời gian thực)
- Đa đích: Xây dựng lớp định tuyến, xử lý các lỗi một phần. ✅ (Cấu hình trong UI)
- Giám sát: Xây dựng cảnh báo cho các lần chuyển giao thất bại. ✅ (Kênh thông báo)
Đối với một dự án phụ, đó là vài tuần làm việc. Đối với hệ thống sản xuất, đó là hàng tháng bảo trì.
Bảo mật là trên hết
Bảo mật webhook không phải là tùy chọn. UpSec sử dụng:
- So sánh HMAC an toàn về thời gian: Ngăn chặn các cuộc tấn công thời gian (timing attacks) có thể làm rò rỉ thông tin chữ ký.
- Giới hạn tốc độ: 100 sự kiện/phút cho mỗi điểm cuối để ngăn chặn lạm dụng.
- TLS mọi nơi: Mọi lưu lượng webhook đều được mã hóa trong quá trình chuyển tiếp.
- Cô lập Payload: Mỗi không gian làm việc có quyền truy cập dữ liệu bị cô lập.
Kế tiếp
Tôi đang tích cực xây dựng UpSec và rất mong nhận được phản hồi từ cộng đồng:
🔗 Website: upsec.co 📖 Tài liệu: upsec.co/docs 🚀 Product Hunt: producthunt.com/posts/upsec
Nếu bạn đã từng gặp vấn đề về độ tin cậy của webhook, tôi rất muốn nghe câu chuyện của bạn. Những nhà cung cấp nào gây ra nhiều rắc rối nhất cho bạn? Bạn muốn những tính năng nào trong một cổng webhook?
Nếu bài viết này hữu ích, hãy cân nhắc bỏ phiếu cho UpSec trên Product Hunt — điều đó thực sự giúp ích rất nhiều! 🙏
Bài viết liên quan

Phần mềm
Anthropic ra mắt Claude Opus 4.7: Nâng cấp mạnh mẽ cho lập trình nhưng vẫn thua Mythos Preview
16 tháng 4, 2026

Công nghệ
Qwen3.6-35B-A3B: Quyền năng Lập trình Agentic, Nay Đã Mở Cửa Cho Tất Cả
16 tháng 4, 2026

Công nghệ
Spotify thắng kiện 322 triệu USD từ nhóm pirate Anna's Archive nhưng đối mặt với bài toán thu hồi
16 tháng 4, 2026
