Verifikasi Signature Webhook
Siapa pun yang tahu (atau menebak) callback URL Anda bisa mengirim POST request yang terlihat seperti webhook. Verifikasi signature adalah yang sebenarnya membuktikan sebuah request datang dari Baiyar — jangan pernah memercayai payload webhook tanpa itu.
Header signature
Bagian berjudul "Header signature"Setiap request membawa header X-Baiyar-Signature:
X-Baiyar-Signature: t=1725267120,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bdt— Unix timestamp saat request ditandatangani.v1—HMAC-SHA256(webhook_secret, "<t>.<raw request body>"), hex-encoded.
Memverifikasi request
Bagian berjudul "Memverifikasi request"- Ambil
tdanv1dari header. - Hitung ulang HMAC atas
"<t>.<raw body>"menggunakan webhook secret Anda (dari Konfigurasi Webhook). - Bandingkan dengan
v1menggunakan perbandingan constant-time. - Tolak request jika
tlebih dari 300 detik dari waktu Anda saat ini, untuk mencegah payload yang direkam diputar ulang di kemudian hari.
import crypto from "node:crypto";
function verifyWebhook(rawBody, signatureHeader, secret) { const [tPart, v1Part] = signatureHeader.split(","); const timestamp = Number(tPart.split("=")[1]); const signature = v1Part.split("=")[1];
if (Math.abs(Date.now() / 1000 - timestamp) > 300) { throw new Error("Signature timestamp terlalu lama"); }
const expected = crypto .createHmac("sha256", secret) .update(`${timestamp}.${rawBody}`) .digest("hex");
const isValid = expected.length === signature.length && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!isValid) { throw new Error("Signature webhook tidak valid"); }}import hashlibimport hmacimport time
def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> None: parts = dict(part.split("=", 1) for part in signature_header.split(",")) timestamp = int(parts["t"]) signature = parts["v1"]
if abs(time.time() - timestamp) > 300: raise ValueError("Signature timestamp terlalu lama")
expected = hmac.new( secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256 ).hexdigest()
if not hmac.compare_digest(expected, signature): raise ValueError("Signature webhook tidak valid")Selanjutnya
Bagian berjudul "Selanjutnya"Menangani Pengiriman Webhook — apa yang harus dilakukan setelah request terverifikasi: merespons dengan benar, retry, dan idempotency.