Shopify OAuth授权SHA256 HMAC签名验证失败排查
Shopify OAuth HMAC签名校验失败修复方案
你的代码存在3个核心问题,直接会导致哈希计算结果不匹配:
- 参数取值与拼接逻辑硬编码,未做正确的参数处理
你目前手动硬编码拼接host/shop/timestamp三个参数,首先无法保证取值是URL解码后的原始值(比如host参数是base64字符串,URL传递时可能存在编码字符,直接取URL里的原始串拼接会和Shopify的计算基准不一致);其次硬编码参数列表无法兼容Shopify后续新增的回调参数——只要是回调URL里除hmac外的所有查询参数,无论你是否识别,都必须全部参与签名计算,少任何一个参数结果都会完全错误。 - 大概率用错了签名密钥
Shopify OAuth回调的HMAC校验密钥是应用的Client Secret(即API Secret Key),不是API公钥、Admin API私有访问令牌、App Proxy签名密钥,很多开发者会在这里拿错凭证直接导致校验失败。 - 参数排序逻辑不可靠
你手动写死参数顺序虽然刚好符合三个参数的字典序,但后续加参数时很容易顺序出错,必须通过代码自动按参数名的ASCII码升序排列,不能手动维护顺序。
另外你尝试的base64格式比对是完全错误的方向,Shopify返回的hmac参数是SHA256哈希的十六进制小写字符串,直接和digest('hex')的结果比对即可,不需要转base64。
可直接复用的正确实现代码(Node.js)
const crypto = require('crypto'); /** * 校验Shopify OAuth回调HMAC签名 * @param {string} callbackFullUrl Shopify跳转的完整回调URL * @param {string} clientSecret 应用的Client Secret(API Secret Key) * @returns {boolean} 签名是否合法 */ function verifyShopifyHmac(callbackFullUrl, clientSecret) { const parsedUrl = new URL(callbackFullUrl); const searchParams = parsedUrl.searchParams; // 提取URL中携带的HMAC值 const incomingHmac = searchParams.get('hmac'); if (!incomingHmac) return false; // 移除hmac参数,剩余所有参数全部参与签名计算 searchParams.delete('hmac'); // 按参数名ASCII升序排序,拼接为key=value&key=value格式 // URLSearchParams会自动完成URL解码,拿到参数原始值 const signContent = Array.from(searchParams.entries()) .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)) .map(([key, val]) => `${key}=${val}`) .join('&'); // 计算HMAC SHA256哈希,输出十六进制格式 const calculatedHmac = crypto .createHmac('sha256', clientSecret) .update(signContent, 'utf8') .digest('hex'); // 使用时序安全比较,避免时序攻击风险 return crypto.timingSafeEqual( Buffer.from(calculatedHmac), Buffer.from(incomingHmac) ); } // 调用示例 const isSignValid = verifyShopifyHmac( 'https://my-appp.com/shopify_oauth?hmac=xxx&host=xxx&shop=xxx×tamp=xxx', '替换为你自己应用的Client Secret' );
额外注意避坑
- 拼接签名内容时,不要对拼接后的字符串做任何二次URL编码,Shopify计算签名时用的是URL解码后的原始参数值
- 不要遗漏任何查询参数,哪怕是你业务逻辑里用不到的参数,只要不是
hmac就必须参与计算 - 确认密钥没有前后空格、换行等多余字符,复制密钥时很容易带入不可见字符
- 不要直接用
===比较哈希值,timingSafeEqual可以避免时序攻击漏洞
内容的提问来源于stack exchange,提问作者InquisitiveTom
相关产品推荐
相关产品推荐

