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

Backend2026-10-07TryQuickToolBox

Webhookが強力でありながら壊れやすい理由

Webhookはリアルタイム連携を支えます:決済通知、CI/CDトリガー、チャットメッセージなど。しかし、2つの大きな課題があります:セキュリティ(リクエストが期待された送信元からのものだとどうやって確認するか?)と信頼性(受信側がダウンしていたらどうするか?)です。この記事では、署名付きペイロードとリトライ戦略で両方に対処する方法を紹介します。

Webhookとは何か?

Webhookとは、イベントが発生したときにプロバイダーからコンシューマーへ送信されるHTTP POSTリクエストです。ポーリングとは異なり、Webhookはほぼリアルタイムでデータをプッシュするため、レイテンシとサーバー負荷を軽減します。プロバイダーはリクエストが真正であることを保証し、コンシューマーはそれを確実に処理する必要があります。

署名付きペイロードでWebhookを保護する

署名付きペイロードは、秘密鍵を使ってリクエストボディの暗号署名(通常はHMAC-SHA256)を生成します。受信側は署名を再計算し、ヘッダー内の署名と比較します。一致すれば、ペイロードは真正で改ざんされていないことになります。

署名の生成と検証方法

典型的なフローは次のとおりです:

  1. プロバイダーとコンシューマーが秘密鍵を共有する(例:ダッシュボード経由)。
  2. プロバイダーがHMAC-SHA256(secret, payload)を計算し、X-Signatureのようなヘッダーで送信する。
  3. コンシューマーが生のボディを読み取り、同じHMACを計算し、定数時間関数で比較する。

Node.jsの例:

const crypto = require('crypto');

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

タイミング攻撃を防ぐため、常に定数時間比較を使用してください。検証前にボディをパースしないこと—生のボディミドルウェアを使用してください。

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

署名があっても、ネットワーク障害や一時的な停止によりWebhook配信が失敗することがあります。堅牢なリトライ機構が最終的な配信を保証します。

リトライ戦略

Pythonでのリトライロジックの例:

import time
import requests

def send_webhook(url, payload, max_retries=5):
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=payload, timeout=5)
            if response.status_code == 200:
                return True
        except requests.RequestException:
            pass
        time.sleep(2 ** attempt)  # exponential backoff
    return False

Webhookコンシューマーのベストプラクティス

比較:ポーリング vs Webhook

項目ポーリングWebhook
レイテンシ高い(間隔ベース)低い(リアルタイム)
サーバー負荷常時リクエストイベント時のみ
複雑さシンプルリトライ/セキュリティが必要
ユースケース小規模、更新頻度が低いリアルタイム連携

FAQ

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

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

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

普遍的な回数はありませんが、指数バックオフで3〜5回が一般的です。その後は手動レビュー用にイベントをログに記録します。

Webhook署名にHMACの代わりにJWTを使えますか?

はい、一部のプロバイダーはJWTを使用しています。原則は同じです:ペイロードを信頼する前にトークンの署名とクレームを検証します。

Webhookペイロードやログを確認する必要がありますか?JSON Formatterを使って、JSONペイロードをすばやく整形して検証できます。