ericcj/amz_sp_api

Getting ExpiredTokenException even though I'm refreshing the token when cache expires.

Opened this issue · 2 comments

Hello, first of all thanks for this gem! It's great so far and I'm looking forward to exploring more features.
I am running into an issue where ever so often (usually about 1-2 hours) something is going wrong and I'm getting an ExpiredTokenException.

{"date"=>"Mon, 31 Oct 2022 17:15:15 GMT", "content-type"=>"application/json", "content-length"=>"135", "x-amzn-requestid"=>"...", "x-amzn-errortype"=>"ExpiredTokenException", "x-amz-apigw-id"=>"....."} Response body: { "errors": [ { "message": "The security token included in the request is expired", "code": "Unauthorized" } ] } :

I am roughly using the same code from the readme to configure the gem and have placed this in an initializer. i am using the iam role strategy to authenticate. Is there an issue with having it in an initializer vs calling it more regularly? I'm running this within a rails app and when I reboot the app, things seem to correct themselves so wondering if this code is meant to execute more regularly than in an initializer. Perhaps the "SecureRandom.uuid" is something that needs to be refreshed along with the token?

require 'aws-sdk-core'
require 'amz_sp_api'
require 'fulfillment-outbound-api-model'

  AmzSpApi.configure do |config|
    config.refresh_token = 
    config.client_id = 
    config.client_secret = 

     config.credentials_provider = Aws::STS::Client.new(
         region: AmzSpApi::SpConfiguration::AWS_REGION_MAP['eu'],
         access_key_id: ,
         secret_access_key: 
    ).assume_role(role_arn: my_role_arn , role_session_name: SecureRandom.uuid)

    config.region = 'eu'
    config.timeout = 20 # seconds
    # config.debugging = true

    # optional lambdas for caching LWA access token instead of requesting it each time, e.g.:
    config.save_access_token = -> (access_token_key, token) do
      Rails.cache.write("SPAPI-TOKEN-#{access_token_key}", token[:access_token], expires_in: token[:expires_in] - 60)
    end
    config.get_access_token = -> (access_token_key) { Rails.cache.read("SPAPI-TOKEN-#{access_token_key}") }
  end

The above code is in an initializer. Separately I call the api executing functions like in the example

  begin
    api = AmzSpApi::FulfillmentOutboundApiModel::FbaOutboundApi.new(AmzSpApi::SpApiClient.new)
    p api.list_all_fulfillment_orders.payload
  rescue AmzSpApi::ApiError => e
    puts "Exception when calling SP-API: #{e}"
  end

I don't know of any reason to run the initialization more than once but i use aws_access_key_id not credentials_provider and I'm unclear on how/if save_access_token/get_access_token interacts with it...maybe try removing those so it's not caching at all and see if the problem goes away?

@ishields did you figure this out? I just run through the exactly same problem and same error as you.