phpoauthsignature

Failing to generate correct OAuth 1.0 signature with PHP


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

Solution

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