تأیید یک تحویل
`verifyWebhookSignature`: با زمان ثابت، بههمراه یک پنجرهٔ بازپخش، و بازگرداندن رویداد تجزیهشده.
در یک هندلر درخواست
URL یک وبهوک عمومی است. هر چیزی روی اینترنت میتواند JSON با شکل درست را به آن POST کند، پس هندلری که بدون بررسی امضا payload.type را میخواند یک API نوشتنِ باز است.
import { verifyWebhookSignature } from '@openemail/sdk' export async function POST(request: Request) { try { const event = await verifyWebhookSignature({ payload: await request.text(), headers: request.headers, secret: process.env.OPENEMAIL_WEBHOOK_SECRET!, toleranceSeconds: 300, }) console.log(event.type, event.data) } catch { return new Response('bad signature', { status: 400 }) } return new Response(null, { status: 204 })}بدنهٔ خام را بدهید. تجزیه و سریالسازی دوباره، ترتیب کلیدها و فاصلهها را تغییر میدهد و امضا تطبیق نخواهد یافت. headers یک object از نوع Headers یا یک object ساده مانند req.headers در Node میگیرد، و X-OpenEmail-Signature با هر شکلی از بزرگی و کوچکی حروف پیدا میشود.
دو چیز که این تابع رسیدگی میکند و بررسی دستساز معمولاً نمیکند: MAC را در زمان ثابت مقایسه میکند، پس پیشوند درست را نمیتوان با زمانسنجی بازیابی کرد، و تحویلی را که بیش از toleranceSeconds در هر دو جهت کهنه باشد رد میکند، که مگر خلافش را بگویید پنج دقیقه است، تا یک درخواست ضبطشده برای همیشه قابل بازپخش نباشد. toleranceSeconds: 0 بررسی بازپخش را خاموش میکند. هر دو باگ خاموشاند. هندلری با هرکدامشان از هر تستی که به فکرتان برسد سربلند بیرون میآید.
در هر شکستی throw میکند: نبودن هدر X-OpenEmail-Signature، هدری که به شکل t=<seconds>,v1=<hex> نباشد، مهر زمانی بیرون از پنجره، یا امضایی که تطبیق نیابد. در موفقیت به بدنهٔ تجزیهشده بهصورت WebhookPayload resolve میشود، پس JSON.parse دومی نیست که اشتباه انجامش دهید. برای تایپ کردن data یک آرگومان تایپ مانند EmailOpenedData بدهید.
به globalThis.crypto.subtle نیاز دارد، که Node 20+، Bun، Deno و Cloudflare Workers همگی فراهمش میکنند.