amz-tools / amazon-sp-api

Amazon Selling Partner API Client
MIT License
231 stars 119 forks source link

oAuth Example in Docs #7

Closed kingkong404 closed 3 years ago

kingkong404 commented 3 years ago

Hey

Do you think it would be possible to add an example of how to do oAuth using the SP API to the docs based off https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#website-workflow

  1. generating the oAuth client
  2. getting the URI for a client to login to amazon
  3. generating the token
  4. refreshing the token
  5. etc

Thanks!

amz-tools commented 3 years ago

Hi,

as we haven't implemented the oAuth logic into our own project yet I'm afraid we can't provide that for now. As soon as we have though, we will be happy to include it in the docs. Maybe in the meantime somebody else is around who can share an example.

kingkong404 commented 3 years ago

Hey @amz-tools is the library designed to support clients? I've managed to generate the login URL and get back the success codes but I'm struggling with Step 4 - generating a client using the LWA credentials.

Can the library generate LWA refresh tokens? and generate a client using the LWA credentials or am I going to have to use a 3rd party oAuth library to manage this.

amz-tools commented 3 years ago

Hi @Stevenje,

just realising that my last comment probably wasn't very helpful to the original question. :-)

No, its currently not possible with the library. You can only request a LWA authorization code for customers who have authorized you via MWS before. No Oauth logic included yet.

kingkong404 commented 3 years ago

No worries! Thanks for the help! :)

Tanveer-LowCoder commented 3 years ago

So, I cracked this, in case someone wants to refer this.

I used the Website workflow, so bear that in mind.

Step 1: Create a button on your web app that opens an external website as follows:

https://sellercentral.amazon.com/apps/authorize/consent?application_id=&state=abc&version=beta

When you create an app on SP, do not forget to add the Auth URL (not important for website flow) and Redirect URL (very important). Configure this redirect URL to capture and store the fields that come back, most important of which is the spapi_auth_code

Step 2: Once you have stored the spapi_auth_code, fire the following POST request:

https://api.amazon.com/auth/o2/token

Header: Content-Type=application/x-www-form-urlencoded

Params: grant_type=authorization_code code=spapi_auth_code from step 1 client_id=Client ID from the developer app client_secret=Client Secret from the developer app redirect_uri= same redirect URI as you have added when creating the app within the SP

You get the Refresh Token back - which is what you will use going forward.

You can use this Refresh Token in the package. :)

kingkong404 commented 3 years ago

@Tanveer-LowCoder Legend! Thanks a million.

Tanveer-LowCoder commented 3 years ago

I created a AWS server with the code, available at https://rapidapi.com/user/integrationhub in case anyone wants to quickly test the API. I can add more if required.

kingkong404 commented 3 years ago

@Tanveer-LowCoder Just got round to trying to set this up today and I'm getting 500 Internal Sever Errors returned from https://api.amazon.com/auth/o2/token

x-amzn-ErrorType: InternalFailure:http://internal.amazon.com/coral/com.amazon.coral.service/

Do you know if everything is operational on AWS' end?

Heres my code incase it's something I'm doing.

    const response = await axios.post("https://api.amazon.com/auth/o2/token", null, {
      params: {
        grant_type: "authorization_code",
        code: "ANmZeXXXXXXXM",
        client_id: "amzn1.application-oa2-client.xxxxxxxxxx72",
        client_secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        redirect_uri: "https://demo.com/success",
      },
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
    });
kingkong404 commented 3 years ago

Update: It seems to be something to do with Axios setting Content-Length=0 header by default

What library did you use to make the request?

kingkong404 commented 3 years ago

@Tanveer-LowCoder Ugh I'm still stuck on this... any help would be great.

krachtstefan commented 3 years ago

@Stevenje I think you called the post method wrong. The second parameter should not be null. This should work:

const response = await axios.post(
  "https://api.amazon.com/auth/o2/token",
  {
    grant_type: "authorization_code",
    code: "ANmZeXXXXXXXM",
    client_id: "amzn1.application-oa2-client.xxxxxxxxxx72",
    client_secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    redirect_uri: "https://demo.com/success",
  },
  { headers: { "Content-Type": "application/x-www-form-urlencoded" } }
);
kingkong404 commented 3 years ago

@Stevenje I think you called the post method wrong. The second parameter should not be null. This should work:

const response = await axios.post(
  "https://api.amazon.com/auth/o2/token",
  {
    grant_type: "authorization_code",
    code: "ANmZeXXXXXXXM",
    client_id: "amzn1.application-oa2-client.xxxxxxxxxx72",
    client_secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    redirect_uri: "https://demo.com/success",
  },
  { headers: { "Content-Type": "application/x-www-form-urlencoded" } }
);

When I do that I get back the following error as it's being sent as data rather than URL params. The null option is to state that no data is being sent.

    data: {
      error_description: 'The authorization grant type is not supported by the authorization server',
      error: 'unsupported_grant_type'
    }

Are you using Axios as well?

krachtstefan commented 3 years ago

I use the request module, but tested the axios method before posting it. Unfortunately I did not post the right headers:

{ 'Content-Type':'application/json' }