تخطَّ إلى المستندات
Java

التحقق من الويب هوك

تحقق من توقيع التسليم قبل أن تثق بما يقوله.

التحقق من تسليم

WebhookHandler.java
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 الترويسة X-OpenEmail-Signature، وتتحقق من قيمة HMAC فيها على الطابع الزمني والجسم في زمن ثابت، وتعيد الحدث على هيئة Map<String, Object>. والسر هو الذي أعادته client.webhooks().create.

الترويسات خريطة أسماؤها بأي حالة أحرف وقيمة كل منها نص أو قائمة نصوص، لذا تصلح exchange.getRequestHeaders() وHttpHeaders في Spring كما هي. وقيمة الترويسة نفسها تصلح أيضًا.

مرّر الجسم الخام كما وصل تمامًا. الجسم الذي حُلِّل ثم رُمِّز من جديد لم يعد يطابق توقيعه.

التسليمات القديمة

Tolerance.java
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());}

التسليم الذي مضى عليه أكثر من خمس دقائق يُرفض، فلا يمكن إعادة تشغيل طلب ملتقَط لاحقًا. تمرير Duration وسيطًا أخيرًا يغيّر الدقائق الخمس، وDuration.ZERO يقبل تسليمًا بأي عمر.

  • الترويسة المفقودة أو المشوّهة، والتوقيع غير المطابق، والتسليم القديم جدًا، كلها ترمي WebhookSignatureException.
  • بعد تدوير السر، قد يحمل التسليم أكثر من توقيع، ويكفي أن يطابق أحدها.
  • أجب بحالة 2xx بسرعة. التسليم الذي يتلقى أي جواب آخر تُعاد محاولته لاحقًا.