Webhooks prüfen
Prüfen Sie die Signatur einer Zustellung, bevor Sie ihrem Inhalt vertrauen.
Eine Zustellung prüfen
import com.sun.net.httpserver.HttpExchange;import com.sun.net.httpserver.HttpHandler;import java.io.IOException;import java.nio.charset.StandardCharsets;import java.util.Map;import uk.openemail.OpenEmail;import uk.openemail.exception.WebhookSignatureException; public final class WebhookHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { String rawBody = new String(exchange.getRequestBody().readAllBytes(), StandardCharsets.UTF_8); String secret = System.getenv("OPENEMAIL_WEBHOOK_SECRET"); int status = 204; try { Map<String, Object> event = OpenEmail.verifyWebhookSignature(rawBody, exchange.getRequestHeaders(), secret); System.out.println(event.get("type") + " " + event.get("id")); } catch (WebhookSignatureException error) { status = 400; } exchange.sendResponseHeaders(status, -1); exchange.close(); }}OpenEmail.verifyWebhookSignature liest den Header X-OpenEmail-Signature, prüft dessen HMAC über Zeitstempel und Körper in konstanter Zeit und gibt das Ereignis als Map<String, Object> zurück. Das Secret ist das, das client.webhooks().create zurückgegeben hat.
Die Header sind eine Map mit Namen in beliebiger Schreibweise und Text oder einer Liste von Texten als Wert, sodass exchange.getRequestHeaders() und die HttpHeaders von Spring unverändert passen. Der Wert des Headers selbst funktioniert ebenfalls.
Übergeben Sie den rohen Körper, genau wie er ankam. Ein Körper, der geparst und neu kodiert wurde, passt nicht mehr zu seiner Signatur.
Alte Zustellungen
String signature = "t=1767225600,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd";Map<String, String> headers = Map.of("X-OpenEmail-Signature", signature); try { OpenEmail.verifyWebhookSignature("{}", headers, System.getenv("OPENEMAIL_WEBHOOK_SECRET"), Duration.ofMinutes(1));} catch (WebhookSignatureException error) { System.err.println(error.getMessage());}Eine Zustellung, die älter als fünf Minuten ist, wird abgelehnt, sodass eine abgefangene Anfrage später nicht erneut abgespielt werden kann. Eine Duration als letztes Argument ändert die fünf Minuten, und Duration.ZERO akzeptiert eine Zustellung jeden Alters.
- Ein fehlender oder fehlerhafter Header, eine Signatur, die nicht passt, und eine zu alte Zustellung werfen alle eine
WebhookSignatureException. - Nachdem ein Geheimnis rotiert wurde, kann eine Zustellung mehr als eine Signatur tragen, und jede passende genügt.
- Antworten Sie schnell mit einem 2xx-Status. Eine Zustellung, die eine andere Antwort bekommt, wird später erneut versucht.