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
相关产品推荐
相关产品推荐

