首页 > 解决方案 > 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."}

标签: phphere-api

解决方案


我也有同样的问题,这里是工作代码:

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>';

推荐阅读