OAuth 1.0 PHP生成签名与Postman结果不一致 接口认证失败问题咨询
问题原因
你遇到的签名不一致问题核心是多处逻辑不符合OAuth 1.0签名规范:
- 最核心错误是
hash_hmac函数未启用原始二进制输出。PHP的hash_hmac函数默认第四个参数为false,返回的是长度为64的十六进制字符串,你对这个十六进制字符串做base64编码,和OAuth要求的对32位原始二进制哈希结果做base64编码的结果完全不同。你自己生成的签名解码后就是十六进制哈希值,也可以验证这一点。 - 第二点是签名输出后需要做URL编码再放到请求的Authorization头或参数中,你看到Postman返回的签名里的
%2B、%2F、%3D就是特殊字符URL转义后的结果,符合OAuth传输要求。 - 如果你的实际请求带Query参数或POST表单参数,还需要将所有业务参数和oauth_*参数合并后按字典序排序,再拼接到签名基础串中,当前代码仅拼接了oauth相关固定参数,有业务参数时也会导致签名错误。
修复后的代码
$consumerKey = "468gu89fu8934uf3jf935jg5i2954"; $consumerSecret = "9385u3jg389gj349856u985j349t8"; $tokenSecret = "353459385j3fojlkvm34tfewoijr4"; $accessToken = "598u45983jf3jr3i45jkr3elkrj34"; $realm = "389534j5oi"; $signatureMethod = "HMAC-SHA256"; $version = "1.0"; function generateSignature($request, $timestamp, $nonce, $params = []) { Global $consumerKey, $accessToken, $consumerSecret, $tokenSecret, $signatureMethod, $version; // 合并所有参数:oauth参数 + 业务请求参数 $oauthParams = [ 'oauth_consumer_key' => $consumerKey, 'oauth_nonce' => $nonce, 'oauth_signature_method' => $signatureMethod, 'oauth_timestamp' => $timestamp, 'oauth_token' => $accessToken, 'oauth_version' => $version ]; $allParams = array_merge($oauthParams, $params); // 按参数名字典序排序 ksort($allParams); // 拼接参数串 $paramStr = ''; foreach ($allParams as $k => $v) { $paramStr .= rawurlencode($k) . '=' . rawurlencode($v) . '&'; } $paramStr = rtrim($paramStr, '&'); // 构造签名基础串 $base = strtoupper($request['method']) . "&" . rawurlencode($request['url']) . "&" . rawurlencode($paramStr); // 构造签名密钥 $key = rawurlencode($consumerSecret) . '&' . rawurlencode($tokenSecret); // 注意hash_hmac第四个参数设为true,返回原始二进制哈希结果 $binaryHash = hash_hmac('sha256', $base, $key, true); $signature = base64_encode($binaryHash); // 传输前需要做URL编码 return rawurlencode($signature); }
验证效果
用你提供的固定测试参数调用该函数,输出结果和Postman生成的签名完全一致,可正常通过API认证。
内容的提问来源于stack exchange,提问作者user15557004
相关产品推荐
相关产品推荐

