sto cercando di calcolare una firma per effettuare chiamate API Amazon, ma continuo a ricevere il seguente errore:Problemi calcolo firma per Amazon Marketplace API
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.
ho avvolto il processo di creazione di una firma in un classe:
<?php
namespace App\Marketplace\Amazon;
class Signature
{
protected $signedString;
public function __construct($url, array $parameters, $secretAccessKey)
{
$stringToSign = $this->calculateStringToSign($url, $parameters);
$this->signedString = $this->sign($stringToSign, $secretAccessKey);
}
protected function calculateStringToSign($url, array $parameters)
{
$url = parse_url($url);
$string = "POST\n";
$string .= $url['host'] . "\n";
$string .= $url['path'] . "\n";
$string .= $this->getParametersAsString($parameters);
return $string;
}
protected function sign($data, $secretAccessKey)
{
return base64_encode(hash_hmac('sha256', $data, $secretAccessKey, true));
}
protected function getParametersAsString(array $parameters)
{
uksort($parameters, 'strcmp');
$queryParameters = [];
foreach ($parameters as $key => $value) {
$queryParameters[$key] = $this->urlEncode($value);
}
return http_build_query($queryParameters);
}
protected function urlEncode($value)
{
return str_replace('%7E', '~', rawurlencode($value));
}
public function __toString()
{
return $this->signedString;
}
}
Ma non posso per la vita di me vedere dove sto andando male. Ho seguito la guida nell'API e ho esaminato l'esempio Java e l'antiquato SDK PHP di Marketplace *.
EDIT: Ed ecco come lo sto utilizzando la classe Signature
:
$version = '2011-07-01';
$url = 'https://mws.amazonservices.com/Sellers/'.$version;
$timestamp = gmdate('c', time());
$parameters = [
'AWSAccessKeyId' => $command->accessKeyId,
'Action' => 'GetAuthToken',
'SellerId' => $command->sellerId,
'SignatureMethod' => 'HmacSHA256',
'SignatureVersion' => 2,
'Timestamp' => $timestamp,
'Version' => $version,
];
$signature = new Signature($url, $parameters, $command->secretAccessKey);
$parameters['Signature'] = strval($signature);
try {
$response = $this->client->post($url, [
'headers' => [
'User-Agent' => 'my-app-name',
],
'body' => $parameters,
]);
dd($response->getBody());
} catch (\Exception $e) {
dd(strval($e->getResponse()));
}
Per inciso: io so le credenziali Marketplace sono corrette come ho collegato al conto e ha recuperato la chiave di accesso, l'ID segreto e il venditore.
* Non sto utilizzando l'SDK in quanto non supporta la chiamata API di cui ho bisogno: SubmitFeed
.
io non sono sicuro di quello che il corpo del 'amazonEncode()' il metodo sta facendo, ma mi sembra di fare ciò che dice la documentazione nel mio 'segno()' metodo, ma usando le funzioni 'base64_encode' e' hash_hmac'. Puoi spiegare la differenza? Inoltre, la documentazione fornita è per AWS, non MWS. –
È simile, la generazione della firma per entrambi. Avrai bisogno di URI codificare il base64 generato, che è quasi quello che fa il mio amazonEncode. –
Ho avvolto il risultato del mio metodo 'sign()' nella funzione 'amazonEncode()', ma sto ancora ricevendo l'errore 'SignatureDoesNotMatch'. –