Inside things

Thursday, July 09, 2009

Inside Signed AWS with PHP and SOAP

Today I decided to update my AWS (Amazon Web Services) code (now called Product Advertising API) to use the new signed requests. Soon all request will need to be signed or else Amazon will just ignore them. I came with what I think to be a pretty elegant solution so I thought I could share it with the world. It uses the SOAP version of the service, and will only work on PHP >= 5.1. Any comments will be appreciated.

function aws_call($action, $body, $locale = 'US')
{
$access_key_id = 'your public access key';
$secret_access_key = 'your secret access key';

$locale_url = '';
if ($locale != 'US') {
$locale_url = "$locale/";
}
$client = new SoapClient('http://ecs.amazonaws.com/AWSECommerceService/2009-06-01/' . $locale_url . 'AWSECommerceService.wsdl');

$timestamp = gmdate("Y-m-d\TH:i:s\Z");
$signature = $action . $timestamp;
$signature = base64_encode(hash_hmac("sha256", $signature, $secret_access_key, True));
$headers = array();
$headers[] = new SoapHeader('http://security.amazonaws.com/doc/2007-01-01/',
'AWSAccessKeyId',
$access_key_id);
$headers[] = new SoapHeader('http://security.amazonaws.com/doc/2007-01-01/',
'Timestamp',
$timestamp);
$headers[] = new SoapHeader('http://security.amazonaws.com/doc/2007-01-01/',
'Signature',
$signature);

$result = $client->__soapCall($action, array($body), NULL, $headers);
}

An example for calling this function

$body = array (
"SubscriptionId" => "your subs-ID",
"Request" => array (
"ResponseGroup" => "EditorialReview,Images",
"ItemId" => $this->asin,
"IdType" => "ASIN",
)
);

$result = aws_call('ItemLookup', $body);

Hope you like it and find it useful.

Labels: