php - HERE REST API 错误:“签名不匹配。授权签名或客户端凭据错误。”
问题描述
我正在尝试使用 PHP 在 HERE REST API 中获取访问令牌,但不断收到错误消息“签名不匹配。授权签名或客户端凭据错误。”。
我正在遵循此页面上的说明:https ://developer.here.com/olp/documentation/access_control/api-reference-swagger.html但他们没有提供生成签名的明确示例,我已经尝试了每一个我能想到的可能的组合/方法。
这是我的代码:
function getHereApiAccessToken()
{
$API_URL="https://account.api.here.com/oauth2/token";
$nonce=uniqid();
$signing_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxx-xxxxxxxxxxxxxxx-xxxxx_x-xxxxxxxxxxxxxx"; //here.access.key.secret
$signature_elements=array();
$signature_elements['oauth_consumer_key']="xxxx_xxxxxx-xxxxxxxxxx";
$signature_elements['oauth_nonce']=$nonce;
$signature_elements['oauth_signature_method']="HMAC-SHA256";
$signature_elements['oauth_timestamp']=time();
$signature_elements['oauth_version']="1.0";
ksort($signature_elements);
$base_string="";
foreach($signature_elements as $key=>$val)
{
$base_string.=urlencode($key).'='.urlencode($val).'&';
}
$base_string=rtrim($base_string, "&");
$signature=hash_hmac('sha256', $base_string, $signing_key, true);
$signature_base64=base64_encode($signature);
$headers=array();
$headers[]="Content-Type: application/x-www-form-urlencoded";
$headers[]='Authorization: OAuth oauth_consumer_key="'.urlencode($signature_elements['oauth_consumer_key']).'", oauth_nonce="'.urlencode($nonce).'", oauth_signature="'.urlencode($signature_base64).'", oauth_signature_method="'.urlencode($signature_elements['oauth_signature_method']).'", oauth_timestamp="'.time().'", oauth_version="'.urlencode($signature_elements['oauth_version']).'"';
$postData=array();
$postData['grant_type']="client_credentials";
$postData['expires_in']=50;
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $API_URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
$response=curl_exec($ch);
br($response);
$httpcode=curl_getinfo($ch, CURLINFO_HTTP_CODE);
if(curl_error($ch))
{
echo "cURL error: ". curl_error($ch);
return false;
}
elseif($httpcode!=200)
{
echo "API responded with HTTP code: ". $httpcode;
echo "<br><br />Response: ".$response;
return false;
}
else
{
curl_close($ch);
$json=json_decode($response, 1);
br($json);
if(empty($json))
{
echo "Failed to decode JSON";
return false;
}
if(empty($json['access_token']))
{
echo "Missing access_token in API response: ".var_export($json, true);
}
return $json['access_token'];
}
return false;
}
以及错误响应的副本:
{"errorId":"ERROR-c3d5c184-f2c9-4edb-a85c-2dd4c6d7e0d1","httpStatus":401,"errorCode":401300,"message":"Signature mismatch. Authorization signature or client credential is wrong.","error":"invalid_client","error_description":"errorCode: '401300'. Signature mismatch. Authorization signature or client credential is wrong."}
解决方案
我也有同样的问题,这里是工作代码:
function generate_string($input, $strength = 16) {
$input_length = strlen($input);
$random_string = '';
for($i = 0; $i < $strength; $i++) {
$random_character = $input[mt_rand(0, $input_length - 1)];
$random_string .= $random_character;
}
return $random_string;
}
$httpUrl = "https://account.api.here.com/oauth2/token";
$permitted_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$nonce= generate_string($permitted_chars, 6);
$signature_elements=array();
$signature_elements['grant_type']="client_credentials";
$signature_elements['oauth_consumer_key']="#here.access.key.id#";//from config file
$signature_elements['oauth_nonce']=$nonce;
$signature_elements['oauth_signature_method']="HMAC-SHA256";
$signature_elements['oauth_timestamp']=time();
$signature_elements['oauth_version']="1.0";
$signing_key="#here.access.key.secret#"; //from config file
$base = 'POST'
. '&' . rawurlencode($httpUrl)
. '&' . rawurlencode('grant_type=client_credentials&oauth_consumer_key=' . $signature_elements['oauth_consumer_key'])
. rawurlencode('&oauth_nonce=' . $signature_elements['oauth_nonce'])
. rawurlencode('&oauth_signature_method=' . $signature_elements['oauth_signature_method'])
. rawurlencode('&oauth_timestamp=' . $signature_elements['oauth_timestamp'])
. rawurlencode('&oauth_version=' . $signature_elements['oauth_version']);
$key = rawurlencode($signing_key) . '&';
$signature = rawurlencode(base64_encode(hash_hmac('sha256', $base, $key, true)));
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $httpUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "grant_type=client_credentials",
CURLOPT_HTTPHEADER => array(
"authorization: OAuth oauth_consumer_key=\"" . $signature_elements['oauth_consumer_key'] . "\",oauth_signature_method=\"" . $signature_elements['oauth_signature_method'] . "\",oauth_timestamp=\"" . $signature_elements['oauth_timestamp'] . "\",oauth_nonce=\"" . $signature_elements['oauth_nonce'] . "\",oauth_version=\"" . $signature_elements['oauth_version'] . "\",oauth_signature=\"{$signature}\"",
"content-type: application/x-www-form-urlencoded",
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
echo '<pre>';
print_r(json_decode($response, true));
echo '</pre>';
推荐阅读
- c# - 无法反序列化当前的 JSON 数组(例如 [1,2,3])& {“解析值时遇到意外字符:e. Path '', line 0, position 0.”}
- tensorflow - torch.nn.LSTM 是否等于 tf.nn.rnn_cell.BasicLSTMCell?
- gradle - Gradle 应用程序构建不包含自己的 jar
- directadmin - 禁用一个域的直接管理员访问权限,设置另一个位置进行管理
- javascript - 输入范围滑块值应指向页面加载时 cgi 脚本值的输出
- google-chrome - 摘要式身份验证请求中的 HTTP 无授权字段
- javascript - 特定于 Instagram 应用内浏览器的 WooCommerce 结帐问题
- laravel - 如何从配置文件中获取值并在 laravel 模型文件中的 $attribute 变量中设置?
- sql-server - 使用 SQL Server 2012 查找日期和时间之间的冲突
- unreal-engine4 - UE4中如何获取材质的粗糙度?