署名付きWebhookの検証

多くのサービスでは、送信するWebhookに署名を付けています。これにより、受信側はリクエストが本当にそのサービスから送信されたものであり、送信途中で改ざんされていないことを確認できます。Webhookの認証方法をHMACに設定すると、Shopify Flowにリクエストが届く前に、アプリがその署名を検証します。検証に失敗したリクエストは、401というステータスで拒否され、ワークフローは実行されません。

設定方法は2つあります。リストから送信者を選ぶか、署名の方法を指定するかです。

組み込みプロバイダー

「Signature provider」からプロバイダーを選択し、その署名用シークレットを貼り付けてください。その後、アプリはそのプロバイダーが指定する方法(適切なヘッダー、エンコーディング、署名付きコンテンツ、リプレイウィンドウ)を検証するため、他に設定する必要はありません。各プロバイダーには、エンドポイントの作成からShopify Flowワークフローの構築に至るまで、独自のセットアップガイドが用意されています。

プロバイダー セットアップガイド また、以下の内容も扱っています
Calendly CalendlyをShopify Flowに連携する方法 -
Customer.io Customer.ioをShopify Flowに連携する方法 -
GitHub GitHubをShopify Flowに連携させる方法 -
レモン・スクイーシー Lemon SqueezyをShopify Flowに接続する方法 -
線形 LinearをShopify Flowに接続する方法 -
モリー MollieをShopify Flowに接続する方法 -
パドル PaddleをShopify Flowに接続する方法 -
Paystack PaystackをShopify Flowに連携する方法 -
Razorpay RazorpayをShopify Flowに連携する方法 -
正気 SanityをShopify Flowに接続する方法 -
Sendcloud SendcloudをShopify Flowに連携する方法 -
セントリー SentryをShopify Flowに接続する方法 -
Shopify ShopifyをShopify Flowに接続する方法 -
Slack SlackをShopify Flowに連携させる方法 -
スクエア SquareをShopify Flowに連携する方法 -
標準のWebhook Standard WebhooksをShopify Flowに接続する方法 OpenAI、Supabase Auth Hooks
ストライプ StripeをShopify Flowに連携する方法 -
Svix SvixをShopify Flowに接続する方法 事務員、再送信、スーパーウォール
Typeform TypeformをShopify Flowに連携する方法 -
Vercel VercelをShopify Flowに接続する方法 -
WooCommerce WooCommerceをShopify Flowに連携させる方法 -
Zendesk ZendeskをShopify Flowに連携させる方法 -

どのガイドにも、その送信者についてアプリが具体的にどのような項目を確認するのか、またその署名用秘密鍵がどこにあるのかが詳しく記載されています。

HMAC認証を採用し、署名プロバイダーとしてStripeを使用するWebhookについて、「署名用シークレット」フィールドの説明、その検証内容、および「Stripeに接続」の手順をご紹介します。
署名付き送信元(ここではStripe):プロバイダーを選択し、その署名用シークレットを貼り付けると、エディタにチェックされている項目と接続方法が表示されます。

カスタム署名:その他の送信者

送信者がリストにない場合は、**「カスタム署名」**を選択し、その署名の方法を記述してください。ご利用のプロバイダーのドキュメントには、次のような記述があります:

X-Acme-Signature = hex(hmac_sha256(secret, timestamp + "." + body))

その一行で、すべてのフィールドに対する答えが得られます:

設定 例から その意味
署名ヘッダー X-Acme-Signature 署名が含まれているヘッダー
アルゴリズム hmac_sha256 SHA-256、SHA-1、またはSHA-512
エンコーディング hex hex、base64、またはbase64url
署名付きペイロード {timestamp}.{body} 署名された正確な文章は以下の通りです
タイムスタンプ X-Acme-Timestamp のようなヘッダー timestampの値がどのように渡されるか
リプレイ許容度 300秒 これより古いリクエストは拒否してください

署名付きペイロード

以下のプレースホルダーを使用して、差出人が署名する内容をご記入ください:

プレースホルダー ~になります
{body} リクエスト本文の生のデータ(バイト単位)。必須です。
{timestamp} ヘッダーまたは署名ヘッダーからのタイムスタンプ
{url} 送信者側で入力された、このWebhookのURLです
{header:name} 別のリクエストヘッダーの値

一般的な形式:{body}、{timestamp}.{body}、{timestamp}{body}、v0:{timestamp}:{body}、{header:webhook-id}.{timestamp}.{body}。**「プロバイダーから開始」**機能を使用して、類似した形式をコピーし、異なる部分のみを変更してください。

署名の位置

  • プレーン:ヘッダーの値は署名であり、必要に応じて、sha256= や v1, といった、ご自身で指定したプレフィックスの後に続きます。
  • キー = 値:このヘッダーには、t=1700000000,v1=abc... のようなペアが格納されます。署名を格納するキー(v1)と、必要に応じてタイムスタンプを格納するキー(t)を指定し、ペアが , または ; で区切られるかを指定してください。

ヘッダーにスペースで区切られた複数の署名が含まれている場合(秘密鍵をローテーションしている際に、一部の送信者がそうすることがあります)、一致する署名が1つでもあれば、それを受け入れます。

その秘密

通常は、送信者が表示した通りにシークレットを貼り付けます。一部の送信者は、whsec_...のように、プレフィックス付きのBase64エンコードされたキーを提供する場合があります。その場合は、**「Base64エンコード」**を選択し、削除したいプレフィックスを入力してください。

本番運用開始前のテスト

署名テスターは設定画面の下部にあり、保存されていない変更内容でも動作します。

  • 実際のリクエストの本文とヘッダーを貼り付け、**「検証」**をクリックしてください。ヘッダーの検出、署名の読み取り、タイムスタンプの範囲確認、ペイロードの構築、署名の照合といった各ステップの詳細と、実際に署名された正確なテキストが表示されます。そのため、不一致が生じた場合でも、単に「無効な署名」と表示されるだけでなく、どこで問題が発生したのかが具体的にわかります。
  • **「有効な例を生成」を実行すると、**現在の設定に基づいて、正しく署名されたヘッダーと、すぐに実行可能なcurlが生成されます。そのリクエストが受け入れられれば、設定はエンドツーエンドで一貫性が保たれています。

このテスターはワークフローを開始することはなく、履歴にも何も記録されず、ご利用のプランの使用量にはカウントされません。

署名が一致しません。何をチェックすればよいでしょうか?▾

順に、秘密鍵(余分なスペースや誤った環境の鍵など、最も一般的な原因)、署名付きペイロード(タイムスタンプと本文の間に.または:が欠落している場合)、エンコーディング(hexとbase64の違い)、そして送信者とアプリの間で何かが本文を変更したかどうか、という順です。 署名は生のバイト列を対象としているため、JSONのフォーマットを再構築するプロキシによって署名が破損してしまいます。

リクエストが「タイムスタンプが許容範囲外」というエラーで失敗します▾

送信側の時計がずれているか、リクエストが遅延したか、古いタイムスタンプで再試行されたか、あるいはタイムスタンプの単位が間違っている可能性があります。送信側で秒、ミリ秒、またはISO日付のどれが使用されているかをご確認ください。

私の送信者は、まず認証のためのハンドシェイクを行う必要があります▾

一部のサービス(Zoom、Dropbox、Asana、Trello、Notion)では、イベントを送信する前に、エンドポイントが認証チャレンジに応答する必要があります。その方法はサービスごとに異なります。そのため、これらのサービスはワンクリックプロバイダーとして提供されていません。これらのサービスをご利用になりたい場合は、送信者の名前を明記の上、サポートまでご連絡ください。

その署名はどこかに保存されていますか?▾

いいえ。「履歴」および「ライブリクエストインスペクタ」では、署名ヘッダーは非表示になっています。これは、許容範囲内で署名が再送信される可能性があるためです。