Webhook署名検証のやり方と受信テスト(LINE・Stripe・GitHub・Slack ほか)

Webhook は、サービスの側から自分のサーバーへ HTTP リクエストを送ってくる仕組みです。作っている途中は「そもそも届いているのか」「中身はどんな形か」「署名の検証がなぜ通らないのか」が分かりにくくなりがちです。このページでは、送信元ごとに確かめる点をまとめます。Webhook が初めての人は、先にはじめてのフック箱を読むと分かりやすいです。

まず、届いているかを確かめる

  1. フック箱で受信用 URL を発行し、送信元の Webhook の送り先に貼ります。
  2. 送信元の管理画面から、テスト送信や実際の操作を行います。
  3. 届けば一覧に出ます。出なければ、送信元の設定(URL の打ち間違い、Webhook が有効になっているか、送るイベントの種類)を見直します。

中身の形が分かったら、フック箱が作る curl コマンドで、自分の開発中のサーバー(localhost など)へ同じリクエストを送り直して動作を確かめられます。

署名の検証が通らないときに多い原因

送信元ごとの署名の仕組み

送信元署名ヘッダー署名する文字列形式
LINEx-line-signature本文HMAC-SHA256・Base64チャネルシークレット
StripeStripe-Signaturet=…,v1=…{t}.{本文}HMAC-SHA256・16進署名シークレット(whsec_…
ShopifyX-Shopify-Hmac-SHA256本文HMAC-SHA256・Base64アプリのクライアントシークレット
GitHubX-Hub-Signature-256sha256=…本文HMAC-SHA256・16進Webhook の Secret
SlackX-Slack-Signaturev0=…v0:{X-Slack-Request-Timestamp}:{本文}HMAC-SHA256・16進Signing Secret
makeshopx-makeshop-signature{x-makeshop-request-timestamp}:{本文}HMAC-SHA256・Base64シークレットキー
Standard Webhookswebhook-signaturev1,…{webhook-id}.{webhook-timestamp}.{本文}HMAC-SHA256・Base64whsec_ の後ろを Base64 デコードしたもの
kintoneなし

フック箱では、受け取ったリクエストを選んで鍵を入れると、上の方法でブラウザの中だけで検証します。鍵はサーバーへ送りません。

LINE(Messaging API)

LINE Developers コンソールの Messaging API 設定にある Webhook URL に、受信用 URL を貼ります。「検証」ボタンを押すと、events が空の配列のリクエストが届きます。これに 200 を返せば検証は成功です。

メッセージのイベントには replyToken が入っています。返信に使えるのは一度だけで、受け取ってすぐに使う必要があります。再送されたイベントは deliveryContext.isRedelivery が true になるので、webhookEventId で二重に処理しないようにします。

Stripe

ダッシュボードの Webhook でエンドポイントを追加し、受信用 URL を貼ります。Stripe-Signaturet はタイムスタンプで、既定では5分より古いものを拒否します。同じイベントが2回以上届くことがあるので、イベント ID で重複を除いてから処理します。テスト環境のイベントは livemode が false です。

Shopify

通知の種類は X-Shopify-Topic(例:orders/create)、店は X-Shopify-Shop-Domain で分かります。同じ通知が2回以上届くことがあるので、X-Shopify-Webhook-Id で重複を除きます。

GitHub

リポジトリの Settings › Webhooks で Payload URL に受信用 URL を貼ります。登録した直後に ping イベントが届きます。Secret を入れていないと X-Hub-Signature-256 は付きません。イベントの種類は X-GitHub-Event、配信ごとの ID は X-GitHub-Delivery です。

Slack

Events API の Request URL を登録すると、typeurl_verification のリクエストが届きます。本文の challenge の値をそのまま返すと登録が通ります。Slack には3秒以内に応答を返す必要があるので、時間のかかる処理は後回しにします。フック箱では「返す応答」の設定で、固定の本文を返せます。

makeshop

署名はタイムスタンプと本文を : でつないだ文字列から作られます。公式では、タイムスタンプが5分より古いものを拒否するよう勧めています。

Standard Webhooks(Svix・Resend など)

webhook-idwebhook-timestampwebhook-signature の3つのヘッダーが付く形式です。鍵は whsec_ の後ろを Base64 デコードしたバイト列です。同じ webhook-id のものは同じ通知の再送です。

kintone

kintone の Webhook には署名がありません。本文の typeADD_RECORDUPDATE_RECORD など)と app で何が起きたかが分かります。受け取る URL を知られないようにし、必要なら送信元の IP アドレスで絞ります。

フック箱を使う

フック箱は登録なし・無料で使えます。受信箱は7日で自動的に消え、保存するのは最新の100件までです。