amzn / selling-partner-api-models

This repository contains OpenAPI models for developers to use when developing software to call Selling Partner APIs.
Apache License 2.0
612 stars 739 forks source link

GET request successing - POST/DELETE/PUT request failing #1674

Closed PhenomEY closed 3 years ago

PhenomEY commented 3 years ago

I got a really funny problem. I can reach every endpoint through GET succesfully but when i use the same headers for a post/delete/put request it fails with

"message": "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.

are there some permissions i missed that are needed for other request methods than GET?

bpyzikvc commented 3 years ago

My first thought is that the canonical string you create for the signature contains 'GET' in it for gets and should be changed to whatever call you are making in all caps. Other than that the signing process should be similar. When I get a signature incorrect error, they usually send me what its supposed to be so compare to what you sent and you should see your issue.

Refer to https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html

PhenomEY commented 3 years ago

@bpyzikvc i am using AWS SDK's SignatureV4 to sign my Psr7 request directly

PhenomEY commented 3 years ago

the generated hash by SignatureV4 is not matching - everything else is fine. The only difference between GET and POST request is that the GET request go a uri query and the POST does not.

In the documentation it says to use a blank space if no query is needed which i am doing... :/

PhenomEY commented 3 years ago

the wrong hash gets build through the request body. So i guess something is missing in my request?

$response = $this->send(
            'POST',
            '/reports/2021-06-30/schedules',
            '',     //queryParams
            ["x-amz-access-token" => $this->accessToken],  //headers
            null,    //body
            '1.1',    //version
            [   // options
                RequestOptions::FORM_PARAMS => [
                    'marketplaceIds' => ['A1PA6795UKMFR9'],
                    'reportType' => 'GET_MERCHANT_LISTINGS_DATA',
                    'period' => 'PT30M'
                ]
            ]
        );

The String-to-Sign should have been

AWS4-HMAC-SHA256
20210726T180624Z
20210726/eu-west-1/execute-api/aws4_request
7c86ec8d5228c25a5c8f5ad8590598138aac28ff5295aaf4ec077605e503dce3

The String to Sign is:

AWS4-HMAC-SHA256
20210726T180624Z
20210726/eu-west-1/execute-api/aws4_request
99434fc19f8a550c762a3b6628ef35558ee7d08dd2dc441299f3c0f96a4ff087
bpyzikvc commented 3 years ago

I think you have an issue in the request like you said. I see you have null there with a comment that that is the body. This should not be null for a POST. For you it would be something like "{ reportType": "GET_MERCHANT_LISTINGS_DATA", marketplaceIds": [ "A1PA6795UKMFR9"], period": "PT30M" }"

PhenomEY commented 3 years ago

My mistake was that i did not use application/json Content Type and tried to pass the data through form_params

It works now with json payload in body