使用Curl调用OVH API时遭遇Invalid signature错误求助
OVH API调用出现Invalid signature签名错误
使用Curl测试域名可用性时,调用OVH API返回Invalid signature签名错误,将自行编写的PHP代码部署到服务器后问题依旧,尝试OVH文档中指定的常规签名生成方式也无法解决。
问题代码
<?php $applicationKey = ""; $applicationSecret = ""; $consumerKey = ""; $domaineAVerifier = "google.com"; $url = "https://eu.api.ovh.com/1.0/domain/zone/{$domaineAVerifier}/status"; $method = "GET"; $nSTime = time(); $sTosign = $applicationSecret . "+" . $consumerKey . "+" . $method . "+" . $url . "+" . $nSTime; $sTmp = hash('sha1', $sTosign); $sTmp = strtolower(str_replace([' ', "\r\n"], '', $sTmp)); $signature = "$1$" . $sTmp; $ch = curl_init($url); $options = array( CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array( "X-Ovh-Application: $applicationKey", "X-Ovh-Consumer: $consumerKey", "X-Ovh-Signature: $signature", "X-Ovh-Timestamp: $nSTime", ), CURLOPT_URL => $url, ); curl_setopt_array($ch, $options); $response = curl_exec($ch); if (curl_errno($ch)) { echo 'Erreur cURL : ' . curl_error($ch); } else { echo $response; } curl_close($ch); ?>
问题排查与修复方案
1. 签名前缀解析错误
代码中$signature = "$1$" . $sTmp;使用双引号包裹$1$,PHP会将$1识别为未定义变量(最终解析为空),导致签名前缀缺失。需改为单引号包裹,避免变量解析:
$signature = '$1$' . $sTmp;
2. 冗余的哈希结果处理
hash('sha1', $sTosign)生成的结果本身就是无空格、无换行的小写字符串,不需要额外执行strtolower(str_replace([' ', "\r\n"], '', $sTmp)),直接使用哈希结果即可。
3. 服务器时间偏差
OVH签名验证对时间戳要求严格,若本地服务器时间与OVH服务器时间偏差超过5分钟,会直接触发签名错误。解决方式:
- 请求
https://eu.api.ovh.com/1.0/auth/time获取OVH官方时间,替换本地time()生成的时间戳 - 同步服务器系统时间,避免后续请求再出现时间偏差
4. 密钥参数校验
确认applicationKey、applicationSecret、consumerKey三个密钥完全正确,无多余空格、拼写错误,且已在OVH后台完成授权配置。
修复后的完整代码
<?php $applicationKey = "你的应用密钥"; $applicationSecret = "你的应用秘钥"; $consumerKey = "你的消费者密钥"; $domaineAVerifier = "google.com"; $url = "https://eu.api.ovh.com/1.0/domain/zone/{$domaineAVerifier}/status"; $method = "GET"; // 优先使用OVH官方时间,避免时间偏差 $ovhTime = file_get_contents("https://eu.api.ovh.com/1.0/auth/time"); $nSTime = $ovhTime ? trim($ovhTime) : time(); // 严格按照OVH要求拼接待签名字符串 $sTosign = $applicationSecret . "+" . $consumerKey . "+" . $method . "+" . $url . "+" . $nSTime; $sTmp = hash('sha1', $sTosign); // 使用单引号包裹签名前缀 $signature = '$1$' . $sTmp; $ch = curl_init($url); $options = array( CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array( "X-Ovh-Application: $applicationKey", "X-Ovh-Consumer: $consumerKey", "X-Ovh-Signature: $signature", "X-Ovh-Timestamp: $nSTime", ), ); curl_setopt_array($ch, $options); $response = curl_exec($ch); if (curl_errno($ch)) { echo 'cURL错误:' . curl_error($ch); } else { echo $response; } curl_close($ch); ?>
内容的提问来源于stack exchange,提问作者Marwen Bouafif
相关产品推荐
相关产品推荐

