如何在PHP Laravel中用HMACSHA256验证Xero Webhook?签名异常排查
Xero Webhook签名验证问题(PHP)
在PHP中验证Xero Webhook时,出现签名不匹配的问题,导致无法完成Intent to receive验证,始终收到提示:Intent to receive required,对签名错误的payload未返回401。
当前代码
$payload = file_get_contents("php://input"); $webhookKey = '-----Webhook Key-----'; $computedSignatureKey = base64_encode(hash_hmac('sha256', $payload, $webhookKey, true)); if ($computedSignatureKey === $_SERVER['HTTP_X_XERO_SIGNATURE']) { return response(200); } return response(401);
签名差异
- Xero返回的签名:
aQGh6OxbmgB1NQnnKrQt0utlrqC4dbAJSC2/Aa2/IE4= - 代码计算出的哈希值:
aQGh6OxbmgB1NQnnKrQt0utlrqC4dbAJSC2KAa2/IE4=
二者的差异在于字符/和K,直接导致签名验证失败。
解决建议
- 核对Webhook密钥:确保
$webhookKey和Xero后台生成的Webhook密钥完全一致,不要包含多余的空格、换行或首尾的无关符号,复制时避免手动修改。 - 确保payload未被篡改:检查是否有框架中间件提前解析了POST请求体,导致
file_get_contents("php://input")获取的不是Xero发送的原始字节流。如果使用Laravel等框架,需要禁用自动解析或者通过原始请求对象获取payload。 - 对比原始payload:将获取到的payload写入日志,和Xero Webhook后台日志中的payload做逐字节对比,确保内容、编码、换行符完全一致。
- 验证哈希计算逻辑:确认
hash_hmac的第四个参数为true(返回原始二进制数据),这一步是正确的,但可以临时输出hash_hmac的原始结果和base64编码后的结果,排查是否在编码环节出现问题。
内容的提问来源于stack exchange,提问作者Jaspreet Singh
相关产品推荐
相关产品推荐

