PHP: Incorrect OAuth 1.0 signature when adding parameters to URL

Long story short, this is my function for generating OAuth 1.0 signature and it works correctly as long as there are no parameters added to URL. Adding even a single parameter results in “Signature invalid” response from the API I’m using this function to connect with.

function generateSignature($request, $timestamp, $nonce) {
  $parameters = array();
  ksort($request['params']);
  foreach($request['params'] as $key=>$value){
    $parameters[] = "$key=".rawurlencode($value);
  }

  $base = $request['method']."&".rawurlencode($request['url'])."&".rawurlencode(implode('&', $parameters))."&"
      .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;
}

The function is then used as follows. Again, this works flawlessly when parameters are absent:

$ch = curl_init();

$request = array();
$request['method'] = 'GET';
$request['url'] = base_url.'/orders';
$params = array();
$params['status'] = 'pending';
$request['params'] = $params;

$parameters = (empty($request['params'])) ? "" : "?".http_build_query($request['params']);

curl_setopt($ch, CURLOPT_URL, $request['url'].$parameters);
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 realm="",oauth_version="1.0",oauth_consumer_key="'.consumer_key.'",oauth_token="'.token.'",oauth_timestamp="'.$timestamp.'",oauth_nonce="'.$nonce.'",oauth_signature_method="HMAC-SHA1",oauth_signature="'.$signature.'"';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

What am I doing wrong? I’ve checked the OAuth 1.0 documentation and examples from StackOverflow and I can’t identify the issue.

Leave a Comment