微信公众号接口验证失败主因是signature生成时字符串排序和编码不一致:需用sha1对echostr、nonce、timestamp按字典序升序拼接哈希,token仅参与排序不参与拼接;常见错误包括数值排序混淆、BOM头干扰、参数类型未统一。

微信公众号接口验证失败:signature 不匹配怎么办
绝大多数人卡在这一步——明明照着文档拼了 signature,但微信服务器返回“token验证失败”。根本原因不是逻辑错,而是字符串排序和编码细节没对齐。
微信要求用 sha1 对三段字符串按字典序升序拼接后哈希:echostr、nonce、timestamp(注意不含 token 本身,但要用它参与排序)。常见错误包括:
- 把
token当作原始参数直接拼进 sha1,实际它只用于排序依据,不参与最终哈希输入 - PHP 中用
$_GET['timestamp']拿到的是字符串,但排序时没统一转为字符串比较,导致"10"排在"2"前面(字典序 vs 数值序) - 没过滤空格或 BOM 头,
file_get_contents('php://input')或 header 里混入不可见字符
实操建议:先硬编码三参数调试,比如 $arr = ['foo', '123', '456']; sort($arr, SORT_STRING); echo sha1(implode('', $arr));,再对照微信文档给的示例值比对输出。
接收微信 XML 消息时 file_get_contents('php://input') 返回空
这是 PHP-FPM + Nginx 环境下高频问题。微信 POST 的是 raw XML,Content-Type 是 text/xml,但默认配置会把非 application/x-www-form-urlencoded 或 multipart/form-data 的请求体丢弃。
关键检查点:
- Nginx 配置中是否含
client_max_body_size限制(微信消息通常小于 2MB,设为5M更稳) - PHP 的
enable_post_data_reading = On(不能关,否则php://input一定为空) - 确认没开启
always_populate_raw_post_data(PHP 5.6+ 已废弃,开反而报错) - 用
var_dump($_SERVER['CONTENT_TYPE'], $_SERVER['REQUEST_METHOD'], file_get_contents('php://input'))直接看原始输入,别依赖$_POST
如果仍为空,临时加一句 if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) $GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input'); 兼容老代码,但本质是环境配置没到位。
调用 curl_init() 请求微信 API 返回 cURL error 60: SSL certificate problem
本地开发环境(尤其是 Windows 或 macOS 自带 PHP)常因 CA 证书路径不对而失败。微信所有接口强制 HTTPS,且校验证书链,不接受跳过验证(CURLOPT_SSL_VERIFYPEER => false 在生产环境绝对禁用)。
正确解法分两步:
- 下载最新 CA 包:从 curl.se/cacert.pem 获取,存为
/path/to/cacert.pem - 在 curl 请求中显式指定:
curl_setopt($ch, CURLOPT_CAINFO, '/path/to/cacert.pem'); - 若用 Guzzle,需在 client 构造时传
['verify' => '/path/to/cacert.pem']
注意:Linux 系统级 CA 通常没问题,但 Docker 容器里可能缺失,得 COPY 进镜像;Mac Homebrew 装的 PHP 有时指向旧证书路径,php -r "print_r(openssl_get_cert_locations());" 可查实际读取位置。
获取用户 openid 后调 get_user_info 接口返回 errcode: 40003
这个错误码明确表示 “invalid openid”,但往往不是 openid 本身错,而是 access_token 权限或 scope 不匹配。
核心约束:
-
get_user_info必须用网页授权获取的access_token(即通过code换来的),不能用全局access_token - 网页授权时
scope必须是snsapi_userinfo(不是snsapi_base,后者只返回 openid) - 该
access_token有效期 2 小时,过期后必须重走授权流程,不能刷新 - 检查 openid 是否被加密传输(如某些代理层自动 base64 编码),打印原始值确认无额外字符
调试时直接用 curl -G "https://api.weixin.qq.com/sns/userinfo" --data-urlencode "access_token=xxx" --data-urlencode "openid=xxx" --data-urlencode "lang=zh_CN" 手动测,排除 PHP 层干扰。
最易被忽略的是:网页授权域名必须在公众号后台「公众号设置 > 功能设置 > 网页授权域名」中精确填写(不带 http://,不支持泛域名),少一个字符或协议不符都会导致 code 换 token 失败,进而让后续所有接口失效。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











