Webhook解説:署名付きペイロードとリトライ戦略

Backend2026-11-10TryQuickToolBox

Webhookが失敗する理由とその修正方法

アプリで注文ステータスを更新するために、決済プロバイダのWebhookを統合したばかりでしょう。テストではすべてがうまくいきますが、本番環境では一部のイベントが届かなかったり、さらに悪いことに重複して受信したりします。適切な保護措置がないと、Webhookはサイレント障害やセキュリティホールの原因になり得ます。

WebhookはイベントによってトリガーされるHTTPコールバックですが、典型的なAPI呼び出しとは異なり、プッシュベースで非同期です。これにより、真正性の検証と配信の保証という2つの核心的な課題が生じます。このガイドでは、署名付きペイロードとスマートなリトライの両方でこれらに対処します。

Webhookとは?

Webhookはユーザー定義のHTTPコールバックです。ソースシステムでイベント(例:新しい支払い)が発生すると、イベントデータを含むHTTP POSTリクエストを指定したURLに送信します。これにより、ポーリングせずにリアルタイムで反応できます。

一般的なユースケースには、支払い通知、CI/CDトリガー、チャット統合などがあります。しかし、Webhookはパブリックインターネットを経由するため、なりすましや損失に対して脆弱です。

署名付きペイロードによるWebhookの保護

Webhookが本当にプロバイダから来たものかをどうやって確認しますか?共有シークレットでペイロードに署名することで、完全性と真正性を保証します。

HMAC署名の仕組み

プロバイダは秘密鍵を使用してリクエストボディのHMAC(例:SHA-256)を計算し、署名をヘッダー(例:X-Signature)に含めて送信します。サーバー側ではHMACを再計算し、タイミング攻撃を防ぐために定数時間比較を使用して比較します。

// Node.jsの例:Webhook署名の検証
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload);
  const digest = hmac.digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}

ベストプラクティス:

信頼性の高いリトライの実装

署名があっても、ネットワークの問題やダウンタイムによりWebhookの配信が失敗することがあります。プロバイダは通常、指数バックオフでリトライしますが、受信側でもリトライを処理する必要があります。

冪等性:安全なリトライの鍵

リトライは重複処理を引き起こす可能性があります。冪等性キー(多くの場合、ペイロードに含まれるかヘッダーとして提供される)を使用して、各イベントが正確に一度だけ処理されるようにします。処理済みのイベントIDを保存し、重複を無視します。

// 例:冪等なWebhookハンドラ
const processedEvents = new Set();

app.post('/webhook', (req, res) => {
  const eventId = req.body.id;
  if (processedEvents.has(eventId)) {
    return res.status(200).send('Already processed');
  }
  // イベントを処理...
  processedEvents.add(eventId);
  res.status(200).send('OK');
});

受信側のリトライ戦略

処理が失敗した場合は、5xxステータスで応答してプロバイダのリトライをトリガーします。一時的なエラーの場合、バックオフ付きの独自のリトライキューを実装することもできます。

シナリオレスポンスアクション
成功200 OKリトライなし
検証エラー400 Bad Requestリトライなし(ペイロードを修正)
サーバーエラー500 Internal Server Errorプロバイダがリトライ
レート制限429 Too Many Requestsプロバイダが遅延後にリトライ

Webhookの監視とデバッグ

受信するすべてのWebhookリクエストをヘッダーとペイロードとともにログに記録します(機密データは秘匿化)。JSON Formatterのようなツールを使用してペイロードを整形表示し、検査を容易にします。配信失敗のアラートを設定し、リトライ回数を追跡します。

FAQ

署名付きWebhookペイロードとは何ですか?

署名付きペイロードには、リクエストが信頼できるソースから来たものであり、改ざんされていないことを検証する暗号署名(通常はHMAC)が含まれます。

失敗したWebhookを何回リトライすべきですか?

ほとんどのプロバイダは指数バックオフで3〜5回リトライします。受信側としては、適切なステータスコードで応答し、プロバイダにリトライを任せます。

HTTPSなしでWebhookを使用できますか?

いいえ—HTTPSはペイロードを暗号化し、中間者攻撃を防ぐために不可欠です。平文HTTPでWebhookを受け入れてはいけません。

Webhookペイロードを検査してデバッグする準備はできましたか?無料のJSON Formatterを試して、JSONデータを即座に整形および検証しましょう。