Ves a la documentació
SDK

Verificar un lliurament

`verifyWebhookSignature`: de temps constant, amb una finestra de repetició, i et torna l'esdeveniment analitzat.

En un gestor de peticions

Una URL de webhook és pública. Qualsevol cosa d'internet hi pot fer POST d'un JSON amb la forma correcta, de manera que un gestor que llegeix payload.type sense comprovar la signatura és una API d'escriptura oberta.

webhook-handler.ts
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 })}

Passa el cos EN CRU. Analitzar-lo i tornar-lo a serialitzar canvia l'ordre de les claus i els espais en blanc, i la signatura no coincidirà. headers accepta un objecte Headers o un objecte pla com ara el req.headers de Node, i X-OpenEmail-Signature es troba sigui quina sigui la seva capitalització.

Dues coses que això gestiona i que una comprovació feta a mà normalment no: compara el MAC en temps constant, de manera que el prefix correcte no es pot recuperar cronometrant-lo, i rebutja un lliurament de més de toleranceSeconds d'antiguitat en qualsevol de les dues direccions, cinc minuts tret que diguis el contrari, de manera que una petició capturada no es pot repetir per sempre. toleranceSeconds: 0 desactiva la comprovació de repetició. Tots dos errors són silenciosos. Un gestor amb qualsevol dels dos supera tots els tests que se't podria ocórrer escriure.

Llança una excepció davant de qualsevol error: una capçalera X-OpenEmail-Signature absent, una que no tingui la forma t=<seconds>,v1=<hex>, una marca de temps fora de la finestra, o una signatura que no coincideix. Si té èxit, es resol amb el cos analitzat com a WebhookPayload, de manera que no hi ha cap segon JSON.parse que puguis fer malament. Passa un argument de tipus com ara EmailOpenedData per tipar data.

Necessita globalThis.crypto.subtle, que proporcionen Node 20+, Bun, Deno i Cloudflare Workers.