我正在尝试使用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."}
答案 0 :(得分:1)
我也有同样的问题,这是工作代码:
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>';
答案 1 :(得分:0)