ドキュメント本文へスキップ
Java

Webhook の検証

配信の内容を信頼する前に、その署名を確認します。

配信を検証する

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 が返したものです。

ヘッダーは、名前の大文字小文字を問わず、値がテキストまたはテキストのリストである map です。そのため exchange.getRequestHeaders() や Spring の HttpHeaders をそのまま渡せます。ヘッダーの値そのものを渡すこともできます。

届いたままの生のボディを渡してください。解析して再エンコードしたボディは、もう署名と一致しません。

古い配信

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

5 分以上前の配信は拒否されるため、傍受されたリクエストをあとで再送することはできません。最後の引数に Duration を渡すとこの 5 分を変更でき、Duration.ZERO にするとどれだけ古い配信でも受け付けます。

  • ヘッダーがない、形式が正しくない、署名が一致しない、配信が古すぎる、のいずれの場合も WebhookSignatureException がスローされます。
  • シークレットをローテーションしたあとは、配信に複数の署名が付くことがあり、どれか 1 つが一致すれば通ります。
  • すばやく 2xx のステータスで応答してください。それ以外の応答を受けた配信は、あとで再試行されます。