I am trying to get Product Reviews from Amazon but getting this error ,
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
Below is my code ,
define('AMAZON_URL','http://webservices.amazon.com/onca/xml?');
define('AMAZON_ACCESS_KEY',--access_key--);
define('AMAZON_SECRET_KEY',--secret_key--);
define('AMAZON_ASSOCIATE_TAG',--tag--);
$dr['model_no'] = --model_no--;
$dr['manufacturer'] = --manufacturer--;
//get amazon data
$timestamp = gmdate("Y-m-d\TH:i:s\Z");//rawurlencode(gmdate("Y-m-d\TH:i:s\Z"));
$url = "AWSAccessKeyId=".AMAZON_ACCESS_KEY;
$url .= "&AssociateTag=".AMAZON_ASSOCIATE_TAG;
$url .= "&IncludeReviewsSummary=True";
$url .= '&Keywords='.$dr['model_no'];
$url .= "&Manufacturer=".$dr['manufacturer'];
$url .= "&Operation=ItemSearch";
$url .= "&ResponseGroup=Reviews";
$url .= "&ReviewSort=HelpfulVotes";
$url .= "&SearchIndex=Electronics";
$url .= "&Service=AWSECommerceService";
$url .= "&Timestamp=".$timestamp;
$url .= "&Version=2013-05-31";
$prepend = "GET\nwebservices.amazon.com\n/onca/xml\n";
$prepend_string = $prepend . $url;
$signature = base64_encode(hash_hmac("sha256", $prepend_string, AMAZON_SECRET_KEY, True));
$signature = str_replace("+", "%2B", $signature);
$signature = str_replace("=", "%3D", $signature);
// $signature = base64_encode(hash_hmac("sha256", $prepend_string, AMAZON_SECRET_KEY, True));
$url = $url.'&Signature=' .$signature;
// $url = $url.'&Signature=' .rawurlencode($signature);
echo "$url\n";
$result = $this->data_api->call_amazon($url);
My call_amazon function is
public function call_amazon($url)
{
$url = AMAZON_URL.$url;
//initialize curl
echo "Caalling url: \n" . $url . "\n";
$ch = curl_init();
//initilize url to set which servvice to call
curl_setopt($ch, CURLOPT_URL, $url);
//to tell curl that post method is used
//tell that retrun value as string
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);
//execute service now
$result = curl_exec($ch);
if(empty($result) || $result===FALSE){
return '<customError>
<status>400</status>
<response>false</response>
</customError>';
} else {
echo "$result \n";
//return response
return $result;
}
}
I had checked the docs and examples and signature looks ok to me. Any suggestions?
Related
I am using Fat Secret API in my project and want to find the food names on search so I hard coded the food name say : banana and it is giving me error
8 Invalid signature: oauth_signature 'NECnoAOp6D2qLCg7YQ84fYyJYRE='
Below is my code
$consumer_key = "bcd69xxxxxxxxxxxxxxxxxxxxxxx52";
$secret_key = "62fe9xxxxxxxxxxxxxxxxxxxxxxxx54d";
$base = rawurlencode("GET")."&";
$base .= "http%3A%2F%2Fplatform.fatsecret.com%2Frest%2Fserver.api&";
$params = "format=json&";
$params = "method=foods.search&";
$params .= "oauth_consumer_key=$consumer_key&";
$params .= "oauth_nonce=".uniqid()."&";
$params .= "oauth_signature_method=HMAC-SHA1&";
$params .= "oauth_timestamp=".time()."&";
$params .= "oauth_version=1.0&";
$params .= "search_expression=banana";
$params .= "oauth_callback=oob";
$params2 = rawurlencode($params);
$base .= $params2;
//encrypt it!
$sig= base64_encode(hash_hmac('sha1', $base, "62fe9d66898545a0b48d497a4394054d&", true));
$url = "http://platform.fatsecret.com/rest/server.api?".$params."&oauth_signature=".rawurlencode($sig);
//$food_feed = file_get_contents($url);
list($output,$error,$info) = loadFoods($url);
echo '<pre>';
if($error == 0){
if($info['http_code'] == '200'){
echo $output;
} else {
die('Status INFO : '.$info['http_code']);
}
}else{
die('Status ERROR : '.$error);
}
function loadFoods($url)
{
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, $url);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
$error = curl_error($ch);
$info = curl_getinfo($ch);
// close curl resource to free up system resources
curl_close($ch);
return array($output,$error,$info);
}
Please Help me in this. I am new in OAuth and Fat Secret API, Please do share the necessary information if you know.
Thanks
I have written a function in PHP to send a CURl request.
The code is given below.
function curl_post($url,$fields,$headers=[],$connect_timeout = 3,$timeout = 20) {
$ch = curl_init();
$postvars = '';
foreach($fields as $key=>$value) {
$postvars .= $key . "=" . $value . "&";
}
$postvars = trim($postvars,'&');
$postvars = json_encode($fields);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST, 1); //0 for a get request
curl_setopt($ch,CURLOPT_POSTFIELDS,$postvars);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT ,$connect_timeout);
curl_setopt($ch,$timeout, 20);
$refined_headers = [];
if(sizeof($headers)) {
foreach($headers as $name => $value) {
$refined_headers[] = "'".$name.": ".$value."'";
}
print_r($refined_headers);
//$refined_headers = ['Content-Type: application/json'];
//echo $refined_headers;exit;
curl_setopt($ch,CURLOPT_HTTPHEADER,$refined_headers);
}
$response = curl_exec($ch);
$info = curl_getinfo($ch,CURLINFO_CONTENT_TYPE);
print_r($info);
curl_close ($ch);
return $response;
}
So I called the function like this
$url = API_ENDPOINT.$method.'/';
$response = curl_post($url,$params_to_send,$headers);
echo $response;
where $url contains my API url and $params contain the parameters as associative array and $headers as follows
$headers = ['Content-Type'=>'application/json'];
My problem is that, the content type header is setting. But when I manually set it inside the curl_post function like
$refined_headers = ['Content-Type: application/json']
it is working perfectly.
What is the problem with my code.
Fixed the issue. The problem was
I put two single quotes before and after the header, which was not needed
$refined_headers[] = "'".$name.": ".$value."'";
I changed that to the following and the issueis resolved.
$refined_headers[] = $name.": ".$value;
I have been trying to follow the steps laid out in the docs for twitter sign in here: https://dev.twitter.com/docs/auth/implementing-sign-twitter
My Code:
$oauth_consumer_secret = '***';
$access_token_secret = '***';
$oauth_consumer_key = '***';
$oauth_nonce = createNonce();
$oauth_signature_method = 'HMAC-SHA1';
$oauth_time = time();
$oauth_token = '***';
$oauth_version = '1.0';
$oauth = array(
'oauth_callback' => '***',
'oauth_consumer_key'=>$oauth_consumer_key,
'oauth_nonce'=>$oauth_nonce,
'oauth_signature_method'=>$oauth_signature_method,
'oauth_timestamp'=>$oauth_time,
'oauth_token'=>$oauth_token,
'oauth_version'=>$oauth_version
);
$baseURI = 'https://api.twitter.com/1.1/oauth/request_token';
$baseString = buildBaseString($baseURI,$oauth);
$compositeKey = getCompositeKey($oauth_consumer_secret,null);
$oauth_signature = base64_encode(hash_hmac('sha1', $baseString, $compositeKey, true));
$oauth['oauth_signature'] = $oauth_signature; //add the signature to our oauth array
$header = array(buildAuthorizationHeader($oauth));
$login = loginUser($baseURI,$header);
echo $login;
function loginUser($baseURI,$header){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baseURI);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
$output = curl_exec($ch);
curl_close($ch);
if ($output!=''){
return $output;
} else {
return 'fail';
};
};
function buildBaseString($baseURI,$params){
$r = array(); // temp array
ksort($params); // sorts params alphabetically by key
foreach($params as $key=>$value){
$r[] = '$key='.rawurlencode($value);
};
return 'POST&'.rawurlencode($baseURI).'&'.rawurlencode(implode('&', $r)); // returns complete base string
};
// Create composite key
function getCompositeKey($consumerSecret,$requestToken){
return rawurlencode($consumerSecret) . '&' . rawurlencode($requestToken);
};
function createNonce(){
$characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
$string = '';
for ($i=0; $i<32; $i++) {
$string .= $characters[rand(0, strlen($characters) - 1)];
};
return $string;
};
function buildAuthorizationHeader($oauth){
$r = 'Authorization: OAuth '; //header prefix
$values = array(); //temporary key=value array
foreach($oauth as $key=>$value)
$values[] = "$key=\"" . rawurlencode($value) . "\""; //encode key=value string
$r .= implode(', ', $values); //reassemble
return $r; //return full authorization header
};
The Problem I am having is that I am getting no response what so ever! So the login function just keeps returning 'fail'.
When I change curlopt_ssl_verifypeer to false I get a HTTP/1.1 401 Unauthorized error.
Any help or clues would be appreciated.
The SSL and OAuth issues are most likely separate.
As for SSL, your certificate authoririty (CA) bundle is most likely out of date. You can either tell curl to not verify the peer CURLOPT_SSL_VERIFYPEER = 0 or update the CA bundle. You can download a current CA bundle here. Most people (myself included) just turn off VERIFYPEER. Although this practice should be discouraged, it's a common solution.
When generating the request token, you do not need oauth_token in your oauth parameters. You are asking for a request token, you don't have one yet. Not sure if this matters, but only use ',' as the delimiter, not ', ' as in $r .= implode(', ', $values); //reassemble
I looked through the rest of your implementation and it looks right. Having written my own, I can appreciate the difficulty here.
I'm trying to retrieve data from Twitter by connecting to twitter API and make some requests the my code below but I get nothing in return... I just requested the bearer token and successfully received it.
This is the code in PHP:
$url = "https://api.twitter.com/1.1/statuses/user_timeline.json?
count=10&screen_name=twitterapi";
$headers = array(
"GET".$url." HTTP/1.1",
"Host: api.twitter.com",
"User-Agent: My Twitter App v1.0.23",
"Authorization: Bearer ".$bearer_token."",
"Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
);
$ch = curl_init(); // setup a curl
curl_setopt($ch, CURLOPT_URL,$url); // set url to send to
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // set custom headers
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return output
$retrievedhtml = curl_exec ($ch); // execute the curl
print_r($retrievedhtml);
when using the print_r nothing is shown at all and when using the var_dump i find "bool(false)"
Any idea with what could be wrong with this?
Regards,
Try outputting any potential cURL errors with
curl_error($ch);
after the curl_exec command. That might give you a clue about what's going wrong. Completely empty responses usually point to something going wrong with the cURL operation itself.
Your headers are wrong... do not include
"GET".$url." HTTP/1.1"
in your headers.
Further, you may print out the HTTP return code by
$info = curl_getinfo($ch);
echo $info["http_code"];
200 is success, anything in the 4xx or 5xx range means something went wrong.
I built based on comments I found in a Twitter dev discussion by #kiers. Hope this helps!
<?php
// Get Token
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, 'https://api.twitter.com/oauth2/token');
curl_setopt($ch,CURLOPT_POST, true);
$data = array();
$data['grant_type'] = "client_credentials";
curl_setopt($ch,CURLOPT_POSTFIELDS, $data);
$screen_name = 'ScreenName'; // add screen name here
$count = 'HowManyTweets'; // add number of tweets here
$consumerKey = 'EnterYourTwitterAppKey'; //add your app key
$consumerSecret = 'EnterYourTwitterAppSecret'; //add your app secret
curl_setopt($ch,CURLOPT_USERPWD, $consumerKey . ':' . $consumerSecret);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$bearer_token = json_decode($result);
$bearer = $bearer_token->{'access_token'}; // this is your app token
// Get Tweets
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, 'https://api.twitter.com/1.1/statuses/user_timeline.json?count='.$count.'&screen_name='.$screen_name);
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Authorization: Bearer ' . $bearer));
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$cleanresults = json_decode($result);
// Release the Kraken!
echo '<ul id="twitter_update_list">';
foreach ( $cleanresults as $tweet ) {
// Set up some variables
$tweet_url = 'http://twitter.com/'.$screen_name.'/statuses/'.$tweet->id_str; // tweet url
$urls = $tweet->entities->urls; // links
$retweet = $tweet->retweeted_status->user->screen_name; // there is a retweeted user
$time = new DateTime($tweet->created_at); // lets grab the date
$date = date_format($time, 'M j, g:ia'); // and format it accordingly
$url_find = array();
$url_links = array();
if ( $urls ) {
if ( !is_array( $urls ) ) {
$urls = array();
}
foreach ( $urls as $url ) {
$theurl = $url->url;
if ( $theurl ) {
$url_block = ''.$theurl.'';
$url_find[] = $theurl; // make array of urls
$url_links[] = $url_block; // make array of replacement link blocks for urls in text
}
}
}
if ( $retweet ) { // add a class for retweets
$link_class = ' class="retweet"';
} else {
$link_class = '';
}
echo '<li'.$link_class.'>';
$new_text = preg_replace('##([\\d\\w]+)#', '$0', $tweet->text); // replace all #mentions with actual links
$newer_text = preg_replace('/#([\\d\\w]+)/', '$0', $new_text); // replace all #tags with actual links
$text = str_replace( $url_find, $url_links, $newer_text); // replace all links with actual links
echo $text;
echo '<br /><a class="twt-date" href="'.$tweet_url.'" target="_blank">'.$date.'</a>'; // format the date above
echo '</li>';
}
echo '</ul>';
I put together some files on github, named "Flip the Bird." Hope this helps...
I created PHP library supporting application-only authentication and single-user OAuth. https://github.com/vojant/Twitter-php.
Usage
$twitter = new \TwitterPhp\RestApi($consumerKey,$consumerSecret);
$connection = $twitter->connectAsApplication();
$data = $connection->get('/statuses/user_timeline',array('screen_name' => 'TechCrunch'));
I have spent the past couple of hours trying all types of variations but according to the Twitter API this should have worked from step 1!
1 addition I have made to the script below is that I have added in:
$header = array("Expect:");
This I found helped in another question on stackoverflow from getting a denied issue / 100-continue.
Issue:
Failed to validate oauth signature and token is the response EVERY time!!!
Example of my post data:
Array ( [oauth_callback] => http://www.mysite.com//index.php [oauth_consumer_key] => hidden [oauth_nonce] => hidden [oauth_signature_method] => HMAC-SHA1 [oauth_timestamp] => 1301270847 [oauth_version] => 1.0 )
And my header data:
Array ( [0] => Expect: )
Script:
$consumer_key = "hidden";
$consumer_secret = "hidden";
function Post_Data($url,$data,$header){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
$data['oauth_callback'] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
$data['oauth_consumer_key'] = $consumer_key;
$data['oauth_nonce'] = md5(time());
$data['oauth_signature_method'] = "HMAC-SHA1";
$data['oauth_timestamp'] = time();
$data['oauth_version'] = "1.0";
$header = array("Expect:");
$content = Post_Data("http://api.twitter.com/oauth/request_token",$data,$header);
print_r($content);
Can anybody see an obvious mistake that I may be making here? Preferably I would not like to go with somebody elses code as most examples have full classes & massive functions, I am looking for the most simple approach!
Your problem is that you did not include the OAuth signature in your request.
You can read about the concept on this page.
A working implementation can be found here.
I faced same issue, what I was missing is passing header in to the curl request.
As shown in this question, I was also sending the $header = array('Expect:'), which was the problem in my case. I started sending signature in header with other data as below and it solved the case for me.
$header = calculateHeader($parameters, 'https://api.twitter.com/oauth/request_token');
function calculateHeader(array $parameters, $url)
{
// redefine
$url = (string) $url;
// divide into parts
$parts = parse_url($url);
// init var
$chunks = array();
// process queries
foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', urlencode_rfc3986($key) . '="' . urlencode_rfc3986($value) . '"');
// build return
$return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", ';
$return .= implode(',', $chunks);
// prepend name and OAuth part
return $return;
}
function urlencode_rfc3986($value)
{
if(is_array($value)) return array_map('urlencode_rfc3986', $value);
else
{
$search = array('+', ' ', '%7E', '%');
$replace = array('%20', '%20', '~', '%25');
return str_replace($search, $replace, urlencode($value));
}
}