Shopify Webhooks

Webhook HMAC 用 hex 算出来永远对不上怎么修

现象#

同一个 body、同一个 secret,本地算出的签名和 header 里的值长度差一倍,比较永远 false,端点持续返回 401,Logs 里一片红色。

原因#

  • X-Shopify-Hmac-Sha256 是 Base64 摘要,digest('hex') 得到的是十六进制,字符集不同
  • 比较时一边按 utf8 转 Buffer、一边按 base64 解码,字节序列不同,timingSafeEqual 直接抛错
  • 部分框架把 header 名转小写或合并成数组,取到的是 undefined 而不是签名字符串
  • 轮换 client secret 后一小时内签名可能仍用旧密钥,刚换完的那批请求必然失败

处理步骤#

  1. 摘要固定为 createHmac('sha256', secret).update(rawBody).digest('base64')
  2. 两边都先 Buffer.from(x, 'base64') 再比,长度不等直接判失败
  3. header 用 req.headers['x-shopify-hmac-sha256'] 取,数组时取第一个元素
  4. 把收到的 header 与本地结果同条日志打印,确认都是 44 位 Base64
  5. 轮换密钥后等一小时再复测,或临时用新旧两个 secret 各算一次

验收标准#

日志里两个 Base64 串完全一致,端点返回 200,连续 10 条投递都不再出现 401。

本文由 风格技术 技术团队整理,适用于 Shopify 标准版与 Plus 店铺。Shopify 平台能力迭代较快,具体操作路径与字段以官方文档和店铺后台实际版本为准。