验证已签名的 Webhook
许多服务会在发送的 Webhook 中添加签名,以便接收方能够验证该请求确实来自该服务,且在传输过程中未被篡改。将 Webhook 的身份验证方式设置为 HMAC 后,应用程序会在任何请求到达 Shopify Flow 之前先验证该签名。未能通过验证的请求将被返回 401 状态码并被拒绝,且绝不会执行工作流程。
有两种设置方法:从列表中选择发件人,或者描述其签名方式。
内置提供程序
在“签名提供商”下选择一个提供商,并粘贴其签名密钥。随后,应用会根据该提供商所记录的方式(正确的标头、编码、签名内容和重放窗口)进行验证,因此无需进行其他配置。每个提供商都有自己的设置指南,内容涵盖从创建端点到构建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 | 如何将 Sentry 连接到 Shopify Flow | - |
| Shopify | 如何将 Shopify 连接到 Shopify Flow | - |
| Slack | 如何将 Slack 与 Shopify Flow 连接起来 | - |
| 正方形 | 如何将Square与Shopify Flow连接起来 | - |
| 标准 Webhook | 如何将标准 Webhook 连接到 Shopify Flow | OpenAI、Supabase 身份验证钩子 |
| Stripe | 如何将 Stripe 连接到 Shopify Flow | - |
| Svix | 如何将Svix连接到Shopify Flow | 文员、重新发送、超级墙 |
| Typeform | 如何将 Typeform 与 Shopify Flow 连接起来 | - |
| Vercel | 如何将 Vercel 连接到 Shopify Flow | - |
| WooCommerce | 如何将WooCommerce与Shopify Flow连接起来 | - |
| Zendesk | 如何将 Zendesk 与 Shopify Flow 连接起来 | - |
每份指南都会详细列出该应用会针对该发件人检查哪些内容,以及如何查找其签名密钥。

自定义签名:其他发件人
如果发件人不在列表中,请选择**“自定义签名**”,并说明其签名方式。您的服务提供商的文档中会包含类似以下内容的一行:
X-Acme-Signature = hex(hmac_sha256(secret, timestamp + "." + body))
这一行代码就解决了所有字段的问题:
| 设置 | 来自该示例 | 其含义 |
|---|---|---|
| 签名页眉 | X-Acme-Signature |
包含签名的标题 |
| 算法 | hmac_sha256 |
SHA-256、SHA-1 或 SHA-512 |
| 编码 | 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),以及键值对是使用,还是;分隔。
如果一个标头包含多个用空格分隔的签名(某些发件人在轮换密钥时会这样做),则任何一个匹配的签名都会被接受。
秘密
通常,您需要按照发件人显示的方式粘贴密钥。有些发件人会提供一个带有前缀的 Base64 编码密钥,例如 whsec_...:请选择**“Base64 编码**”,并输入需要去除的前缀。
上线前的测试
签名测试器位于设置下方,支持对未保存的更改进行测试。
- 粘贴一个真实请求的正文和头部信息,然后点击**“验证”**。您将看到每个步骤 - - 找到头部、读取签名、时间戳在范围内、构建负载、比较签名 - - 以及被签名的确切文本,因此如果出现不匹配,系统会明确指出问题出在哪里,而不是仅仅显示“签名无效”这样的简单提示。
- 生成一个有效的示例,该示例会根据您当前的设置生成签名正确的头部信息,并生成一个可直接运行的
curl。如果该请求被接受,则说明您的配置在端到端上是一致的。
该测试器不会启动任何工作流程,不会向“历史记录”写入任何内容,也不会计入您的套餐配额。
签名不匹配。我应该检查什么?▾
按以下顺序检查:密钥(最常见的原因,包括多余的空格或使用了错误环境的密钥)、带签名的负载(时间戳与正文之间缺少.或:)、编码方式(十六进制与Base64),以及发送方与应用之间是否存在导致负载被篡改的情况。 签名覆盖原始字节,因此会重新格式化 JSON 的代理服务器会破坏这些签名。
请求失败,错误信息为“时间戳超出容差范围”▾
发送方的时钟不准确,请求被延迟或使用了过时的时间戳重新发送,或者时间戳单位有误。请检查您的发送方使用的是秒、毫秒还是 ISO 日期。
我的发件人需要先进行验证握手▾
某些服务(Zoom、Dropbox、Asana、Trello、Notion)会在发送任何事件之前,以各自的方式向端点发送验证请求,端点必须先对此作出响应。正因如此,这些服务并未作为“一键集成”提供商提供。如果您需要其中某项服务,请联系支持团队并提供您的发件人名称。
签名是否存储在某个地方?▾
不。在“历史记录”和“实时请求检查器”中,签名头会被屏蔽,因为签名可以在其容差窗口内被重放。

