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.
2
Answers
OK, found the problem. The string containing the params should be added to the end of the base string:
Thank you for this example, even with it, I struggled for hours before figuring out that if your query param is alphabetically less than "oauth", then you need to move the query param closer to the start of the base. In my case the query param was ‘id’. It seems all of the params in the base string need to be in alpha order so you might have some query params before and some after the oauth params.