node.js で Simple Pay ボタン フォームに署名するための Amazon の指示に従うために、過去 6 時間を費やしました。署名を受け入れることができず、紛らわしい指示のすべての順列を試しました。誰かが私の悲惨さから私を助けることができますか?
私が得るエラーは
入力パラメーターの署名が無効です
これが私の手順です
var params={
"returnUrl": "[confidential]",
"ipnUrl": "[confidential]",
"processImmediate": "1",
"accessKey" :"[AWS key]",
"collectShippingAddress" :"0",
"isDonationWidget" :"0",
"amazonPaymentsAccountId" :"[the button generator creates this but there is no mention in the docs]",
"referenceId" :ref,
"cobrandingStyle" :"logo",
"immediateReturn" :"1",
"amount" :"USD "+amount,
"description" : desc,
"abandonUrl" :"[confidential]",
"signatureMethod": "HmacSHA256", //docs not clear if signatureMethod and signatureVersion should be included, but I've tried all permutations and can't get it to work
"signatureVersion" :"2"
}
//Docs say it should confirm to
/*
StringToSign = HTTPVerb + "\n" +
ValueOfHostHeaderInLowercase + "\n" +
HTTPRequestURI + "\n" +
CanonicalizedQueryString <from the preceding step>
*/
//sort parameters (natural byte order)
var p=_.pairs(params);
var psorted=_.sortBy(p, function(p) { return p[0];});
//start to construct the form
var input='';
for(var i=0; i<psorted.length;i++) {
input+="<input type='hidden' name='"+psorted[i][0]+"' value='"+psorted[i][1]+"'>";
}
//prepare the string to be signed
var qstring='POST'+'\n';
qstring+='https://authorize.payments.amazon.com'+'\n';
qstring+='/pba/paypipeline'+'\n';
for(var i=0; i<psorted.length;i++) {
psorted[i][0]=encodeURI(psorted[i][0]);
psorted[i][1]=encodeURI(psorted[i][1]);
qstring+=psorted[i][0]+'='+psorted[i][1];
if (i<psorted.length-1) {qstring+='&';}
};
console.log(qstring+'\n\n');
var sig=crypto.createHmac("SHA256", "[AWS Secret Key") 6
.update(qstring)
.digest('base64');
input+="<input type='hidden' name='signature' value='"+sig+"'>"; //doesn't matter whether or not i url encode this
console.log(input);
パラメータを次のように変換します
POST
authorize.payments.amazon.com
/pba/paypipeline
abandonUrl=XXXX&accessKey=XXXXX&amazonPaymentsAccountId=XXXXXX&amount=USD%203&cobrandingStyle=logo&collectShippingAddress=0&description=sadasdd&immediateReturn=1&ipnUrl=XXXXXx&isDonationWidget=0&processImmediate=1&referenceId=324324&returnUrl=XXXXXXXX&signatureMethod=HmacSHA256&signatureVersion=2
テストのために、出力をこのフォームに連結して貼り付けます
<form action="https://authorize.payments.amazon.com/pba/paypipeline" method="POST">
<input type='hidden' name='abandonUrl' value='[confidential]'>
<input type='hidden' name='accessKey' value='[confidential]'>
<input type='hidden' name='amazonPaymentsAccountId' value='[confidential]'>
<input type='hidden' name='amount' value='USD 3'>
<input type='hidden' name='cobrandingStyle' value='logo'>
<input type='hidden' name='collectShippingAddress' value='0'>
<input type='hidden' name='description' value='sadasdd'>
<input type='hidden' name='immediateReturn' value='1'>
<input type='hidden' name='ipnUrl' value='[confidential]'>
<input type='hidden' name='isDonationWidget' value='0'>
<input type='hidden' name='processImmediate' value='1'>
<input type='hidden' name='referenceId' value='324324'>
<input type='hidden' name='returnUrl' value='[confidential]'>
<input type='hidden' name='signatureMethod' value='HmacSHA256'>
<input type='hidden' name='signatureVersion' value='2'>
<input type='hidden' name='signature' value='fHSA+p37r5ooOJOUnjYBdhNFe/pAEg/KunAEOudUvGs='>
<input type="submit">
</form>
アマゾンのドキュメントはこちら
http://docs.aws.amazon.com/AmazonSimplePay/latest/ASPAdvancedUserGuide/Sig2CreateSignature.html
署名を生成する方法
署名を作成するには
この手順の後半で必要になる、正規化されたクエリ文字列を作成します。
UTF-8 クエリ文字列コンポーネントをパラメーター名で自然なバイト順で並べ替えます。
パラメーターは、GET URI または POST 本文から取得できます (Content-Type が application/x-www-form-urlencoded の場合)。
次のルールに従って、パラメーター名と値を URL エンコードします。
RFC 3986 で定義されている予約されていない文字を URL エンコードしないでください。
これらの予約されていない文字は、A ~ Z、a ~ z、0 ~ 9、ハイフン (-)、アンダースコア (_)、ピリオド (.)、およびチルダ (~) です。
他のすべての文字を %XY でパーセント エンコードします。ここで、X と Y は 16 進数の 0 ~ 9 と大文字の AF です。
%XY%ZA... 形式の拡張 UTF-8 文字をパーセントエンコードします。
パーセントは、スペース文字を %20 としてエンコードします (一般的なエンコード スキームのように + ではありません)。
Note 現在、すべての AWS サービス パラメータ名は予約されていない文字を使用しているため、エンコードする必要はありません。ただし、将来の使用に備えて、予約文字を使用するパラメーター名を処理するコードを含めることができます。パラメーター値が空の場合でも、エンコードされたパラメーター名をエンコードされた値から等号 ( = ) (ASCII 文字 61) で区切ります。
名前と値のペアをアンパサンド ( & ) (ASCII コード 38) で区切ります。
次の疑似文法に従って、署名する文字列を作成します (「\n」は ASCII 改行を表します)。
StringToSign = HTTPVerb + "\n" + ValueOfHostHeaderInLowercase + "\n" + HTTPRequestURI + "\n" + CanonicalizedQueryString HTTPRequestURI コンポーネントは、クエリ文字列までの URI の HTTP 絶対パス コンポーネントですが、クエリ文字列は含まれません。HTTPRequestURI が空の場合は、スラッシュ ( / ) を使用します。
作成したばかりの文字列、キーとしてシークレット アクセス キー、ハッシュ アルゴリズムとして SHA256 または SHA1 を使用して、RFC 2104 準拠の HMAC を計算します。
詳細については、http://www.ietf.org/rfc/rfc2104.txt にアクセスしてください。
結果の値を base64 に変換します。
結果の値を Signature リクエスト パラメータの値として使用します。
重要 要求で送信する最終的な署名は、RFC 3986 で指定されているように URL エンコードする必要があります (詳細については、 http://www.ietf.org/rfc/rfc3986.txtにアクセスしてください)。ツールキットの URL が最終的な要求をエンコードする場合、必要な署名の URL エンコードを処理します。ツールキットが最終リクエストを URL エンコードしない場合は、署名をリクエストに含める前に必ず URL エンコードしてください。最も重要なことは、署名が 1 回だけ URL エンコードされていることを確認することです。よくある間違いは、署名の形成中に URL を手動でエンコードし、ツールキットの URL がリクエスト全体をエンコードするときに再度エンコードすることです。ボタンを作成するための高度なプロセスについては、「ボタン フォームを動的に作成する」を参照してください。
次の例では、例を読みやすくするために新しい行が挿入されています。明示的な '\n' は改行が必要な場所で使用されます。
以下は、POST を使用した Amazon Simple Pay リクエストの例です。
前の例で StringToSign に使用する文字列の例を次に示します。
POST\n authorize.payments-sandbox.amazon.com\n /pba/paypipeline\n SignatureMethod=HmacSHA256 &SignatureVersion=2 &accessKey=YourCallerKey &amount=USD%201.1 &cobrandingStyle=logo &description=Test%20Widget &immediateReturn=0 &ipnUrl=http%3A %2F%2Fyourwebsite.com%2Fipn &processImmediate=1 &referenceId=YourReferenceId &returnUrl=http%3A%2F%2Fyourwebsite.com%2Freturn.html 署名を生成するその他の例については、「付録: サンプル コード」を参照してください。
ボタン フォームに正しく署名する方法については、「ボタン フォームに正しく署名する方法」を参照してください。