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

Hubspot Webhook V3签名偶尔不匹配问题排查求助

Hubspot V3 Webhook签名校验偶尔失败的原因分析

我开发了一个接收Hubspot Webhook POST请求的服务,采用Hubspot V3签名机制完成请求校验,相关TypeScript代码如下:

const requestSignature = params?.headers?.['x-hubspot-signature-v3']
const requestTimestamp = params?.headers?.['x-hubspot-request-timestamp']

// Validate timestamp
const MAX_ALLOWED_TIMESTAMP = 300000 // 5 minutes in milliseconds
const currentTime = Date.now()
if (currentTime - requestTimestamp > MAX_ALLOWED_TIMESTAMP) {
  throw new GeneralError('Hubspot signature v3 timestamp is invalid')
}

// Calculate signature
const clientSecret = <...snip: get secret from secrets store...>
const body = JSON.stringify(params.body)
const source = params.method + params.uri + body + requestTimestamp
const signature = crypto.createHmac('sha256', clientSecret).update(source).digest('base64')

// Validate signature
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(requestSignature))) {
  throw new NotAuthenticated('Hubspot signature v3 mismatch')
}

该服务大部分时间运行正常,但偶尔会出现签名不匹配的情况。已确认我方数据无误、请求头存在,且并非timingSafeEqual调用问题,确实存在签名不一致的情况。以下是可能导致这类问题的常见原因:

  • 请求体序列化差异:Hubspot发送的原始请求体与你通过JSON.stringify(params.body)生成的字符串可能存在格式差异:
    • 字段顺序:部分框架会自动排序JSON对象的字段,而Hubspot计算签名时使用的是原始字段顺序,两者不一致会导致源字符串不同
    • 空格/缩进:Hubspot的原始请求体通常是无空格的紧凑格式,若你的JSON.stringify带了缩进参数(如JSON.stringify(params.body, null, 2)),会生成不同的字符串
    • 类型转换:如果请求体中的数值、布尔值等在解析后被转换类型(比如字符串类型的数字被转为数值类型),再序列化回去会和原始内容不一致
  • URI路径处理不一致:你使用的params.uri可能和Hubspot计算签名时的路径存在差异:
    • 大小写问题:Hubspot可能使用全小写路径,而你的服务收到的路径包含大写字符
    • 查询参数:若请求带查询参数,Hubspot会将完整的查询串(含参数顺序)纳入签名计算,若你的params.uri遗漏或调整了查询参数顺序,会导致源字符串不匹配
    • 编码差异:特殊字符的编码方式(如空格是+还是%20)双方处理不一致,也会影响签名计算的源字符串
  • 时间戳类型错误:requestTimestamp从请求头获取时是字符串类型,直接参与数值计算或拼接字符串时,可能因隐式转换导致与Hubspot使用的时间戳格式不一致。比如Hubspot使用的是纯数字字符串,而你的代码中若存在类型转换异常,会生成错误的源字符串
  • 重试请求的签名变更:Hubspot在Webhook发送失败时会触发重试,重试请求的时间戳是重试时的当前时间,签名也会基于新时间戳重新生成。若你的服务对重试请求做了不当缓存(比如复用之前的签名校验逻辑),会导致校验失败
  • 字符编码不匹配:请求体的原始编码若不是UTF-8,而JSON.stringify默认使用UTF-8序列化,会导致生成的字节流与Hubspot用于计算签名的原始字节不一致
  • Client Secret不一致:需确认是否存在多环境秘钥混用、秘钥更新后未同步到所有服务实例的情况,部分实例使用旧秘钥校验新请求时会出现签名不匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:35:11