تأیید وبهوکها
پیش از اعتماد به آنچه یک تحویل میگوید، امضای آن را بررسی کنید.
تأیید یک تحویل
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 برگردانده است.
سرآیندها یک map هستند که نامهایشان با هر بزرگی و کوچکی حروف و مقدارشان متن یا فهرستی از متنهاست، پس exchange.getRequestHeaders() و HttpHeaders در Spring همانطور که هستند به کار میآیند. مقدار خودِ سرآیند هم کار میکند.
بدنهٔ خام را، دقیقاً همانطور که رسیده، بدهید. بدنهای که تجزیه و دوباره رمزگذاری شده دیگر با امضایش مطابقت ندارد.
تحویلهای قدیمی
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 پاسخ دهید. تحویلی که هر پاسخ دیگری بگیرد بعداً دوباره امتحان میشود.