You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HubSpot Webhooks V3请求签名验证失败问题求助

HubSpot Webhook签名验证失败的排查与修复

以下是几个可能导致签名不匹配的原因及对应的修复方案:

1. 移除不必要的UTF-8编码

你代码中使用的utf8_encode()会对已为UTF-8格式的原始请求数据造成双重编码,破坏签名所需的字符串结构。直接删除该函数调用即可:

// 原代码
$string = utf8_encode("{$request_method}{$request_uri}{$request_body}{$request_timestamp}");

// 修改后
$string = "{$request_method}{$request_uri}{$request_body}{$request_timestamp}";

2. 确保请求体完全匹配原始内容

HubSpot生成签名依赖未修改的原始请求体,如果你的PHP环境或框架自动解析并重新编码了JSON请求体,会导致空格、换行、键顺序等格式变化,进而签名不匹配:

  • 不要在调用file_get_contents('php://input')前使用$_POST或任何自动解析请求体的方法;
  • 若用框架,关闭该路由的请求体自动解析功能;
  • 用抓包工具对比本地获取的请求体与HubSpot发送的原始内容,确认完全一致。

3. 验证请求URI的准确性

HubSpot使用请求的**完整路径(含查询参数)**生成签名,需确保$_SERVER['REQUEST_URI']与HubSpot发送的完全一致:

  • 检查大小写是否匹配(如HubSpot发送/HubSpot/Webhook.php而你的是小写);
  • 若请求带查询参数(如/hubspot/webhook.php?foo=bar),URI必须包含完整参数部分,不能遗漏。

4. 确认App Secret的正确性

反复核对$HUBSPOT_APP_SECRET是从HubSpot应用后台复制的完整、无错误的值,确保没有多余空格、换行或拼写失误。

修复后的完整代码示例

$request_method = $_SERVER['REQUEST_METHOD'];
$request_uri = $_SERVER['REQUEST_URI'];
// 确保调用此方法前未解析请求体
$request_body = file_get_contents('php://input');
$request_timestamp = $_SERVER['HTTP_X_HUBSPOT_REQUEST_TIMESTAMP'];
$HUBSPOT_APP_SECRET = '你的App Secret';

// 直接拼接原始字符串,不做额外编码
$signature_base = "{$request_method}{$request_uri}{$request_body}{$request_timestamp}";
// 生成HMAC哈希并base64编码
$generated_signature = base64_encode(hash_hmac('sha256', $signature_base, $HUBSPOT_APP_SECRET, true));
// 安全比较签名
$is_valid = hash_equals($_SERVER['HTTP_X_HUBSPOT_SIGNATURE_V3'], $generated_signature);

echo $is_valid ? 'yes' : 'no';

额外排查步骤

  • 用抓包工具(如Charles、Wireshark)捕获HubSpot请求,对比本地获取的request_method、request_uri、request_body、request_timestamp是否与请求完全一致;
  • 检查服务器时间是否与HubSpot同步(时间差过大可能触发重放攻击防护,但不直接影响签名匹配)。

内容的提问来源于stack exchange,提问作者Fllorinaaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:22:49