質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Q&A

0回答

3778閲覧

AmazonのSelling Partner API(SP-API)にて403エラーが発生してしまう

masH-works

総合スコア0

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

0グッド

0クリップ

投稿2021/09/02 16:00

編集2021/09/08 17:47

前提・実現したいこと

AmazonのSP-APIを用いて新規注文の確認を行おうとしています。
Node.jsのaxiosを用いてAPIにリクエストを送っているのですが、
タイトルの通り403エラーが発生してしまいレスポンスを得られていません。
問題点・解決方法をご教示ください。

発生している問題・エラーメッセージ

下記はSP-APIから返ってきたエラーレスポンスです。

json

1{ errors: 2 [ { message: 'Access to requested resource is denied.', 3 code: 'Unauthorized', 4 details: '' } ] }

該当のソースコード

ID等は変更して記載しております。
require部

js

1const axios = require('axios') 2const qs = require('querystring') 3const dateformat = require('dateformat') 4const cryptoJs = require('crypto-js')

アクセストークンを取得する部分です。

js

1// AccessTokenの取得 2const auth = () => { 3 const url = 'https://api.amazon.com/auth/o2/token' 4 const headers = { 5 'Content-Type': 'application/x-www-form-urlencoded' 6 } 7 const query = { 8 grant_type: 'refresh_token', 9 refresh_token: 'Atzr|hogehoge', 10 client_id: 'LWA_client_ID', 11 client_secret: 'LWA_client_secret' 12 } 13 return axios.post(url, qs.stringify(query), { headers: headers }) 14 .catch((err) => { 15 console.log('Error!,Auth') 16 console.log(err.response.data) 17 }) 18}

この部分は成功しており、下記のレスポンスを取得できています。

json

1{ access_token: 2 'Atza|hogehoge', 3 refresh_token: 4 'Atzr|fugafuga', 5 token_type: 'bearer', 6 expires_in: 3600 }

署名キーを取得する部分です。
この部分は下記のページをもとに作成しています。
署名バージョン 4 の署名キーを取得する方法の例
を使用しています。

js

1const accessKey = 'IAM_AccessKey' 2const secretKey = 'IAM_SecretKey' 3const regionName = 'us-west-2' 4const serviceName = 'execute-api' 5 6const getSignatureKey = (key, dateStamp, region, serviceName) => { 7 const kDate = cryptoJs.HmacSHA256(dateStamp, `AWS4${key}`) 8 const kRegion = cryptoJs.HmacSHA256(region, kDate) 9 const kService = cryptoJs.HmacSHA256(serviceName, kRegion) 10 const kSigning = cryptoJs.HmacSHA256('aws4_request', kService) 11 return kSigning 12}

実際にSP-APIにリクエストを送っている部分です。
axios.get(url, { params: query, headers: headers })
の部分までは下記の公式の手順に則って署名処理及びリクエストヘッダの作成を行い、署名は成功しました。
署名バージョン 4 を使用した AWS リクエストへの署名

js

1const order = (token) => { 2 const host = 'sellingpartnerapi-fe.amazon.com' 3 const path = '/orders/v0/orders/' 4 const contentType = 'application/x-www-form-urlencoded' 5 const date = new Date() 6 const charset = 'utf-8' 7 const isoDate = dateformat(date, 'UTC:yyyymmdd"T"HHMMss"Z"') 8 const url = `https://${host}${path}` 9 const userAgent = 'axios/0.21.1' 10 const query = { 11 'CreatedAfter': '2021-07-01', 12 'MarketplaceIds': 'A1VC38T7YXB528', 13 } 14 const canonicalHeader = `content-type:${contentType}; charset=${charset}\nhost:${host}\nuser-agent:${userAgent}\nx-amz-access-token:${token}\nx-amz-date:${isoDate}\n` 15 const signedHeaders = 'content-type;host;user-agent;x-amz-access-token;x-amz-date' 16 const canonicalPayload = cryptoJs.enc.Hex.stringify(cryptoJs.SHA256('')) 17 const canonicalRequest = `GET\n${encodeURI(path)}\n${encodeURI(qs.stringify(query))}\n${canonicalHeader}\n${signedHeaders}\n${canonicalPayload}` 18 const credentialScope = `${dateformat(date, "UTC:yyyymmdd")}/${regionName}/${serviceName}/aws4_request` 19 const signatureString = `AWS4-HMAC-SHA256\n${isoDate}\n${credentialScope}\n${cryptoJs.enc.Hex.stringify(cryptoJs.SHA256(canonicalRequest))}` 20 const signatureKey = getSignatureKey(secretKey, dateformat(date, "UTC:yyyymmdd"), regionName, serviceName) 21 const signature = cryptoJs.enc.Hex.stringify(cryptoJs.HmacSHA256(signatureString, signatureKey)) 22 23 const headers = { 24 'Content-Type': `${contentType}; charset=${charset}`, 25 'Host': host, 26 'User-Agent': userAgent, 27 'x-amz-access-token': token, 28 'X-Amz-date': isoDate, 29 'Authorization': `AWS4-HMAC-SHA256 Credential=${accessKey}/${credentialScope}, SignedHeaders=${signedHeaders},Signature=${signature}` 30 } 31 32 axios.get(url, { params: query, headers: headers }) 33 .then((res) => { 34 console.log('order Success!') 35 console.log(res) 36 }) 37 .catch((err) => { 38 console.log('Error!,Order') 39 console.log(err) 40 console.log(err.response.data) 41 }) 42} 43 44auth().then((response) => { 45 console.log('Auth Success!') 46 order(response.data.access_token) 47})

試したこと

  • アプリケーションのIAM ARNをuser,roleそれぞれに設定し試しました。

下記のポリシーをアタッチしています。
これは下記のリンクを参考に行いましたが、レスポンスは変わりませんでした。
Access to requested resource is denied 403 SP-API AMAZON - C#

json

1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Effect": "Allow", 6 "Action": "execute-api:Invoke", 7 "Resource": "arn:aws:execute-api:*:*:*" 8 } 9 ] 10}
  • ヘッダーの修正

ヘッダー設定部分を下記のように変更しました。

js

1 const headers = { 2 'Content-Type': `${contentType}; charset=${charset}`, 3 'Host': host, 4 'User-Agent': userAgent, 5 'X-Amz-Access-Token': token, 6 'X-Amz-date': isoDate, 7 'Authorization': `AWS4-HMAC-SHA256 Credential=${accessKey}/${credentialScope}, SignedHeaders=${signedHeaders},Signature=${signature}` 8 }

js

1 const headers = { 2 'Content-Type': `${contentType}; charset=${charset}`, 3 'Host': host, 4 'User-Agent': userAgent, 5 'x-amz-access-token': token, 6 'X-Amz-date': isoDate, 7 'Authorization': `AWS4-HMAC-SHA256 Credential=${accessKey}/${credentialScope}, SignedHeaders=${signedHeaders},Signature=${signature}` 8 }

X-Amz-Access-Tokenをすべて小文字に変更しました。
これは下記のIssueを参考に変更しました。
Access token is missing in the request header. #292
これにより、レスポンスは下記のように変わりました。

json

1{ errors: 2 [ { message: 'Access to requested resource is denied.', 3 code: 'Unauthorized', 4 details: 'Access token is missing in the request header.' } ] } 5

json

1{ errors: 2 [ { message: 'Access to requested resource is denied.', 3 code: 'Unauthorized', 4 details: '' } ] } 5

補足情報(FW/ツールのバージョンなど)

$ node -v v10.19.0 $ npm -v 6.14.4

SP-API公式ドキュメント

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問