钉钉机器人签名计算时 URL 编码格式错误导致校验失败怎么办?

文章导读
直接检查签名生成代码中 timestamp 是否参与了 URL 编码,以及最终 sign 值在拼接 URL 时是否做了 URL 编码,大多数校验失败是因为这两步顺序或对象搞错了。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

直接检查签名生成代码中 timestamp 是否参与了 URL 编码,以及最终 sign 值在拼接 URL 时是否做了 URL 编码,大多数校验失败是因为这两步顺序或对象搞错了。

先说结论:签名计算时 timestamp 不应提前编码,最终 sign 必须编码,顺序错乱必失败

  • 先确认:secret 复制是否有空格或换行
  • 先处理:严格按照“时间戳 + 换行 + 密钥”拼接后再哈希
  • 再验证:用 curl 发送请求看返回 errmsg 是否为 ok

命令速用版

import hashlib, hmac, base64, urllib.parse, time
secret = 'SEC...' 
timestamp = str(round(time.time() * 1000))
string_to_sign = f'{timestamp}\n{secret}'
sign = urllib.parse.quote_plus(base64.b64encode(hmac.new(secret.encode(), string_to_sign.encode(), digestmod=hashlib.sha256).digest()))
webhook = f'https://oapi.dingtalk.com/robot/send?access_token=...&timestamp={timestamp}&sign={sign}'

为什么会这样

钉钉机器人加签机制要求使用 HMAC-SHA256 算法,协议规定字符串拼接完成后才进行哈希,最后对哈希结果进行 URL 编码。如果在哈希前对 timestamp 编码,或者哈希后忘记对 sign 编码,都会导致服务端计算出的签名与你发送的不一致。

分步处理

1. 检查密钥:确保 secret 没有多余空格,最好重新复制一次。

2. 检查时间戳:使用当前毫秒级时间戳,不要使用秒级。

钉钉机器人签名计算时 URL 编码格式错误导致校验失败怎么办?

3. 检查拼接:timestamp 和 secret 之间必须有一个换行符 \n。

4. 检查编码:最终 sign 包含特殊字符,必须用 URL Encode 处理。

怎么验证是否生效

发送请求后,观察 HTTP 状态码是否为 200,且返回 JSON 中 errmsg 字段为 ok。如果返回 errcode 不为 0,查看 errmsg 提示。

钉钉机器人签名计算时 URL 编码格式错误导致校验失败怎么办?

常见坑

1. 某些语言默认哈希输出是 hex 字符串,钉钉要求 base64。

2. 时间戳过期,签名有效期通常为请求前后一定时间内,确保服务器时间同步。

3. 二次编码,不要在生成 sign 后再次对整个 URL 进行编码。

参考来源

钉钉开放平台文档中心 - 自定义机器人接入 https://open.dingtalk.com/document/robots/custom-robot-access