skip to Main Content

I’m trying to use vanilla PHP to get some data from an API with oAuth 1.0 authorization. My code is below, the API keeps responding to it with code 401: Invalid signature. As far as I can see, the method for generating signature conforms with examples from documentation and from Stack Overflow, so I’m not sure what I’m doing wrong. Is there perhaps a problem with my nonce?

const consumer_key = "20CECD28B41A458E9E328BB45C26EACB";
const consumer_secret = "F485B390C5854A69A8DA17554E689D03";
const token = "5F3C117598A14BE8B7136659AB2251C0";
const token_secret = "647E14C4F7EF4DA5AA119D5C60E95114";

function generateNonce($timestamp){
    $TimeReduced = substr($timestamp, 0, -2);
    $string = $TimeReduced;
    $hash = hash('sha1', $string, false);
    return $hash;
}

function generateSignature($request, $timestamp, $nonce){
  $base = $request['method']."&".rawurlencode($request['url'])."&"
      .rawurlencode("oauth_consumer_key=".rawurlencode(consumer_key)
      ."&oauth_nonce=".rawurlencode($nonce)
      ."&oauth_signature_method=".rawurlencode("HMAC-SHA1")
      ."&oauth_timestamp=". rawurlencode($timestamp)
      ."&oauth_token=".rawurlencode(token)
      ."&oauth_version=".rawurlencode("1.0"));

    $key = rawurlencode(consumer_secret).'&'.rawurlencode(token_secret);
    $signature = base64_encode(hash_hmac('SHA1', $base, $key, true));
    return $signature;
}

$ch = curl_init();

$request = array();
$request['url'] = 'https://someniceapi.com';
$request['method'] = 'GET';

curl_setopt($ch, CURLOPT_URL, $request['url']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request['method']);

$timestamp = time();
$nonce = generateNonce($timestamp);
$signature = generateSignature($request, $timestamp, $nonce);
$headers = array();
$headers[] = 'Authorization: OAuth oauth_consumer_key="'.consumer_key.'",oauth_token="'.token.'",oauth_signature_method="HMAC-SHA1",oauth_signature='.$signature.'",oauth_timestamp="'.$timestamp.'",oauth_nonce="'.$nonce.'",oauth_version="1.0"';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);

2

Answers


  1. Chosen as BEST ANSWER

    In the end, it was the missing " before signature value. Such a basic error.


  2. You need to base64-encode the hash in its "lower-case hexits" form, not its binary form.

    $signature = base64_encode(hash_hmac('SHA1', $base, $key, true));
    

    hash_hmac with fourth parameter set to true, gets you the binary form.

    $signature = base64_encode(hash_hmac('SHA1', $base, $key));
    

    is what you need.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search