简体   繁体   中英

oAuth “Invalid Signature” When Adding a Flickr API Argument

I'm having trouble with the all-too-common oAuth "invalid signature" issue.

My language is PHP the API I'm trying to interact with is Flickr.

My goal is to call the flickr.contacts.getList method. I'm able to call this method without any problems, as long as I don't pass any arguments with my API call. As soon as I add in an argument (eg, page), my oAuth signature gets invalidated.

For the most part, I'm leveraging someone else's code to do just about everything ( see this blog post ). As a result, I don't fully understand how the oAuth signature is getting built and how it is also getting invalidated. This is where I need some help.

The code directly below WORKS just fine. Note that I am NOT passing the page argument.

$mt = microtime();
$rand = mt_rand();
$oauth_nonce = md5($mt . $rand);
$nonce = $oauth_nonce;
$sig_method = "HMAC-SHA1";
$timestamp = gmdate('U');
$oversion = "1.0";
$request_token_url = 'http://api.flickr.com/services/rest';
$basestring = "format=json&method=flickr.contacts.getList&nojsoncallback=1&oauth_consumer_key=".$consumer_key."&oauth_nonce=".$nonce."&oauth_signature_method=".$sig_method."&oauth_timestamp=".$timestamp."&oauth_token=".$oauth_key."&oauth_version=".$oversion;
$baseurl = "GET&".urlencode($request_token_url)."&".urlencode($basestring);
$hashkey = $consumer_secret."&".$oauth_secret;
$oauth_signature = base64_encode(hash_hmac('sha1', $baseurl, $hashkey, true));
$fields = array
(   
'method'=>'flickr.contacts.getList',
'oauth_nonce'=>$nonce,
'oauth_timestamp'=>$timestamp,
'oauth_consumer_key'=>$consumer_key,
'oauth_signature_method'=>$sig_method,
'oauth_version'=>$oversion,
'oauth_signature'=>$oauth_signature,
'nojsoncallback'=>'1',
'format'=>'json',
);
$fields_string = "";
foreach($fields as $key=>$value)
{
$fields_string .= "$key=".urlencode($value)."&";
}
$fields_string = rtrim($fields_string,'&');
$url = $request_token_url."?".$fields_string;

#Make Flickr API call.
$ch = curl_init();
$timeout = 5; // set to zero for no timeout 
curl_setopt ($ch, CURLOPT_URL, $url); 
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
$file_contents = curl_exec($ch);
curl_close($ch);

The code directly below DOES NOT WORK, as I get an "invalid signature" response from Flickr. Note that this time I am passing the page argument.

$mt = microtime();
$rand = mt_rand();
$oauth_nonce = md5($mt . $rand);
$nonce = $oauth_nonce;
$sig_method = "HMAC-SHA1";
$timestamp = gmdate('U');
$oversion = "1.0";
$request_token_url = 'http://api.flickr.com/services/rest';
$basestring = "format=json&method=flickr.contacts.getList&page=1&nojsoncallback=1&oauth_consumer_key=".$consumer_key."&oauth_nonce=".$nonce."&oauth_signature_method=".$sig_method."&oauth_timestamp=".$timestamp."&oauth_token=".$oauth_key."&oauth_version=".$oversion;
$baseurl = "GET&".urlencode($request_token_url)."&".urlencode($basestring);
$hashkey = $consumer_secret."&".$oauth_secret;
$oauth_signature = base64_encode(hash_hmac('sha1', $baseurl, $hashkey, true));
$fields = array
(
'method'=>'flickr.contacts.getList',
'oauth_nonce'=>$nonce,
'page'=>'1',
'oauth_timestamp'=>$timestamp,
'oauth_consumer_key'=>$consumer_key,
'oauth_signature_method'=>$sig_method,
'oauth_version'=>$oversion,
'oauth_token'=>$oauth_key,
'oauth_signature'=>$oauth_signature,
'nojsoncallback'=>'1',
'format'=>'json',
);
$fields_string = "";
foreach($fields as $key=>$value)
{
$fields_string .= "$key=".urlencode($value)."&";
}
$fields_string = rtrim($fields_string,'&');
$url = $request_token_url."?".$fields_string;

#Make Flickr API call.
$ch = curl_init();
$timeout = 5; // set to zero for no timeout 
curl_setopt ($ch, CURLOPT_URL, $url); 
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
$file_contents = curl_exec($ch);
curl_close($ch);

The only difference between the first and the second code sample is that I have added in an argument. I've done lots of testing, and this issue has nothing to do with the order in which the argument is passed (order doesn't seem to affect the signature). In addition, I've tried other Flickr API methods, and they all exhibit the same behavior (so this issue is not specific to this particular Flickr method).

I figured it out. Order does matter.

In the example above, to add on the page argument, you must add it on at the end of the $basestring variable, like so:

$basestring = "format=json&method=flickr.contacts.getList&page=1&nojsoncallback=1&oauth_consumer_key=".$consumer_key."&oauth_nonce=".$nonce."&oauth_signature_method=".$sig_method."&oauth_timestamp=".$timestamp."&oauth_token=".$oauth_key."&oauth_version=".$oversion."$page=1";

Order does not seem to matter when defining the $fields array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM