yen-jung Chen
yen-jung Chen

Reputation: 33

Amazon Selling Partner API - signed request (ruby implementation)

Following the Amazon Selling Partner API Doc, I was able to get the LWA access token. However, I'm getting blocked in making request to the REST API.

https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#connecting-to-the-selling-partner-api

I tried to use aws-sdk-signer to create a signed request

access_token = 'LWA access token'

signer = Aws::Sigv4::Signer.new(
  access_key_id: 'my access id',
  region: 'us-east-1',
  secret_access_key: 'my access key,
  service: 'execute-api',
)

signature = signer.sign_request(
  http_method: 'GET',
  url: 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders',
  headers: {
    'host' => 'sellingpartnerapi-na.amazon.com',
    'user_agent' => 'test (Language=Ruby)',
    'x-amz-access-token' => access_token
  })

response = HTTParty.send(:get, 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders', headers: {
  'host' => signature.headers['host'],
  'user_agent' => 'test (Language=Ruby)',
  'x-amz-access-token' => access_token,
  'x-amz-content-sha256' => signature.headers['x-amz-content-sha256'],
  'x-amz-date' => signature.headers['x-amz-date'],
  'Authorization' => signature.headers['authorization'],
})

resposne

{"errors"=>[{"message"=>"Access to requested resource is denied.", "code"=>"Unauthorized", "details"=>"Access token is missing in the request header."}]}

It looks like I'm not signing the LWA access token correctly, but I have no idea what's going on since this is a new API and there's not much implementation especially in ruby.

Would anyone give some directions?

Update: I followed the Singer document https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Sigv4/Signer.html

Aws::Sigv4::Signer

Upvotes: 3

Views: 2017

Answers (2)

Jordan Foreman
Jordan Foreman

Reputation: 3888

For anyone stumbling across this:

Your problem likely stems from HTTParty (or other HTTP client gems) using Ruby's Net::HTTPHeader behind the scenes.

Net::HTTPHeader capitalizes all request headers before the request is sent and the x-amz-access-token header is case-sensitive.

If you're populating x-amz-access-token with a valid value and still receiving the following error:

{
    "message": "Access to requested resource is denied.",
    "code": "Unauthorized",
    "details": "Access token is missing in the request header."
}

...then you're likely running into this issue.

You can bypass this by overloading Net:HTTPHeader.capitalize like so:

module Net::HTTPHeader
  def capitalize(name)
    name
  end
  private :capitalize
end

see also: https://github.com/amzn/selling-partner-api-docs/issues/292#issuecomment-759904882

Upvotes: 1

Eric Jensen
Eric Jensen

Reputation: 384

"Access token is missing in the request header" sounds like something is wrong with your x-amz-access-token. Are you retrieving it like this? https://github.com/ericcj/amz_sp_api/blob/main/lib/sp_api_client.rb#L40

Upvotes: 0

Related Questions