我正在尝试为授权标头生成签名以调用 Amazon Shipping API。 也有兴趣知道是否有其他方式集成 Shippin API,因为亚马逊提供了不同的文档,但没有一个文档清楚如何集成。他们的支持团队已告知使用 AWS 签名方法来生成标头,但其 sdk 在 PHP 中不可用。
这是我生成签名的代码,但它总是导致 400 HTTP 错误。
$host = "https://sellingpartnerapi-eu.amazon.com";
$accessKey = ACCESS_KEY;
$secretKey = SECRET_KEY;
$region = "eu-west-1";
$service = "execute-api";
$requestUrl = "https://sellingpartnerapi-eu.amazon.com/shipping/v2/shipments/rates";
$uri = 'shipping/v2/shipments/rates';
function calcualteAwsSignatureAndReturnHeaders($host, $uri, $requestUrl,
$accessKey, $secretKey, $region, $service,
$httpRequestMethod, $data, $debug = TRUE){
$terminationString = 'aws4_request';
$algorithm = 'AWS4-HMAC-SHA256';
$phpAlgorithm = 'sha256';
$canonicalURI = $uri;
$canonicalQueryString = '';
$signedHeaders = 'content-type;host;x-amz-date';
$currentDateTime = new DateTime('UTC');
$reqDate = $currentDateTime->format('Ymd');
$reqDateTime = $currentDateTime->format('Ymd\THis\Z');
// Create signing key
$kSecret = $secretKey;
$kDate = hash_hmac($phpAlgorithm, $reqDate, 'AWS4' . $kSecret, true);
$kRegion = hash_hmac($phpAlgorithm, $region, $kDate, true);
$kService = hash_hmac($phpAlgorithm, $service, $kRegion, true);
$kSigning = hash_hmac($phpAlgorithm, $terminationString, $kService, true);
// Create canonical headers
$canonicalHeaders = array();
$canonicalHeaders[] = 'content-type:application/x-www-form-urlencoded';
$canonicalHeaders[] = 'host:' . $host;
$canonicalHeaders[] = 'x-amz-date:' . $reqDateTime;
$canonicalHeadersStr = implode("\n", $canonicalHeaders);
// Create request payload
$requestHasedPayload = hash($phpAlgorithm, $data);
// Create canonical request
$canonicalRequest = array();
$canonicalRequest[] = $httpRequestMethod;
$canonicalRequest[] = $canonicalURI;
$canonicalRequest[] = $canonicalQueryString;
$canonicalRequest[] = $canonicalHeadersStr . "\n";
$canonicalRequest[] = $signedHeaders;
$canonicalRequest[] = $requestHasedPayload;
$requestCanonicalRequest = implode("\n", $canonicalRequest);
$requestHasedCanonicalRequest = hash($phpAlgorithm, utf8_encode($requestCanonicalRequest));
if($debug){
echo "<h5>Canonical to string</h5>";
echo "<pre>";
echo $requestCanonicalRequest;
echo "</pre>";
}
// Create scope
$credentialScope = array();
$credentialScope[] = $reqDate;
$credentialScope[] = $region;
$credentialScope[] = $service;
$credentialScope[] = $terminationString;
$credentialScopeStr = implode('/', $credentialScope);
// Create string to signing
$stringToSign = array();
$stringToSign[] = $algorithm;
$stringToSign[] = $reqDateTime;
$stringToSign[] = $credentialScopeStr;
$stringToSign[] = $requestHasedCanonicalRequest;
$stringToSignStr = implode("\n", $stringToSign);
if($debug){
echo "<h5>String to Sign</h5>";
echo "<pre>";
echo $stringToSignStr;
echo "</pre>";
}
// Create signature
$signature = hash_hmac($phpAlgorithm, $stringToSignStr, $kSigning);
// Create authorization header
$authorizationHeader = array();
$authorizationHeader[] = 'Credential=' . $accessKey . '/' . $credentialScopeStr;
$authorizationHeader[] = 'SignedHeaders=' . $signedHeaders;
$authorizationHeader[] = 'Signature=' . ($signature);
$authorizationHeaderStr = $algorithm . ' ' . implode(', ', $authorizationHeader);
// Request headers
$headers = array();
$headers[] = 'authorization:'.$authorizationHeaderStr;
$headers[] = 'content-length:'.strlen($data);
$headers[] = 'content-type: application/x-www-form-urlencoded';
$headers[] = 'host: ' . $host;
$headers[] = 'x-amz-date: ' . $reqDateTime;
return $headers;
}
您需要在标头字段中添加“x-amz-access-token”,如下所示
$headers = array();
$headers[] = 'authorization:'.$authorizationHeaderStr;
$headers[] = 'content-length:'.strlen($data);
$headers[] = 'content-type: application/json';
$headers[] = 'host: ' . $host;
$headers[] = 'x-amz-date: ' . $reqDateTime;
$headers[] = 'x-amz-access-token: ' . $reqToken;
生成 x-amz-access-token