使用OAuth 2.0 MAC通过PHP对接Paysera授权时持续返回401错误求助
排查OAuth 2.0 MAC认证对接Paysera接口401未授权问题
以下是几个关键排查点和修复建议:
1. Authorization头参数的引号问题
你当前代码里把每个参数值都用双引号包裹了(比如id="KEY_ID"),但根据MAC认证规范以及多数服务的实现,参数值不需要额外添加双引号。Paysera接口可能因为无法正确解析带引号的参数值而返回401。
修复:修改_getHeader方法里的参数拼接逻辑,去掉引号:
$parts[] = $name . '=' . $value;
2. 默认端口的处理问题
对于HTTPS请求,默认端口是443,根据MAC认证规范,当使用协议默认端口时,签名串里的port字段应该留空,而不是传入443。如果传入了默认端口,会导致签名计算错误。
修复:在调用_getMac前处理端口值:
// 在_getHeader方法中添加端口处理逻辑 $port = $port === 443 ? '' : $port; $mac = $this->_getMac($ts, $nonce, $method, $path, $host, $port, $key);
3. 时间同步问题
MAC认证的ts参数用于防止重放攻击,服务器会校验时间戳是否在允许的时间窗口内(通常5-15分钟)。如果你的服务器本地时间和Paysera服务器时间偏差过大,会直接返回401。
验证:校准本地服务器时间,确保和Paysera服务器时间同步,可使用NTP服务完成时间校准。
4. Nonce格式优化
虽然uniqid()生成的字符串符合规范,但部分服务可能要求nonce具备更高随机性。可以改用更随机的生成方式:
private function _getNonce() { return bin2hex(random_bytes(16)); }
修改后的完整代码示例
private function _getTs() { return time(); } private function _getNonce() { return bin2hex(random_bytes(16)); } private function _getMac($ts, $nonce, $method, $path, $host, $port, $key) { return base64_encode(hash_hmac("sha256", implode("\n", [ $ts, $nonce, $method, $path, $host, $port, "", ]), $key, true)); } private function _getHeader($id, $method, $path, $host, $port, $key) { $ts = $this->_getTs(); $nonce = $this->_getNonce(); // 处理HTTPS默认端口 $port = $port === 443 ? '' : $port; $mac = $this->_getMac($ts, $nonce, $method, $path, $host, $port, $key); $params = [ "id" => $id, "ts" => $ts, "nonce" => $nonce, "mac" => $mac, ]; $parts = []; foreach ($params as $name => $value) { // 去掉参数值的双引号 $parts[] = $name . '=' . $value; } return "MAC " . implode(", ", $parts); } public function test() { $httpClient = new \Bitrix\Main\Web\HttpClient(); $httpClient->setHeader("Authorization", $this->_getHeader( KEY_ID, "GET", "/rest/v1/post-offices", "delivery-api.paysera.com", 443, KEY, )); $httpClient->query("GET", "https://delivery-api.paysera.com/rest/v1/post-offices"); return $httpClient->getResult(); }
额外验证步骤
- 开启HTTP客户端调试模式,查看实际发送的Authorization头内容,确认格式符合要求。
- 对比Paysera官方示例(若有)的签名计算逻辑,确保你的MAC值生成过程一致。
内容的提问来源于stack exchange,提问作者Viacheslav Ravdin
相关产品推荐
相关产品推荐

