Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HERE REST API Error: "Signature mismatch. Authorization signature or client credential is wrong."

Tags:

php

here-api

I am trying to get an access token in HERE REST API using PHP, but keep getting an error saying "Signature mismatch. Authorization signature or client credential is wrong.".

I'm following instructions on this page: https://developer.here.com/olp/documentation/access_control/api-reference-swagger.html but they don't provide clear example of generating the signature and I've tried every possible combination/method that I can think of.

Here is my code:

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

And a copy of the error response:

{"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."}
like image 445
Stan S. Avatar asked Oct 25 '25 14:10

Stan S.


1 Answers

I also had same issue, here is working code:

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>';
like image 118
Mahendra JMJ Avatar answered Oct 27 '25 02:10

Mahendra JMJ