署名をリクエストに追加

広告

最後にリクエストに署名を「Signature」パラメータの値として追加して完成です。

function getSignature(){
  var para = {
    "Service":"AWSECommerceService",
    "AWSAccessKeyId":"00000000000000000000",
    "Operation":"ItemLookup",
    "ItemId":"0679722769",
    "ResponseGroup":"ItemAttributes,Offers,Images,Reviews",
    "Version":"2009-01-06",
    "Timestamp":"2009-01-01T12:00:00Z"
  };

  var para_array = [];

  for(var pname in para){
    para_array.push(pname + "=" + encodeURIComponent(para[pname]));
  }

  para_array.sort();

  var str_para = para_array.join('&');
  var str_signature = "GET" + "¥n" + "webservices.amazon.com" + "¥n" + "/onca/xml" + "¥n" + str_para;

  HMAC_SHA256_init("1234567890");
  HMAC_SHA256_write(str_signature);
  var array_hash = HMAC_SHA256_finalize();

  var str_hash = "";
  for (var i = 0; i < array_hash.length; i++) {
    str_hash += String.fromCharCode(array_hash[i]);
  }

  var signature = Base64.encode(str_hash);
  var para_signature = "&Signature=" + encodeURIComponent(signature);

  location.href = "http://webservices.amazon.com/onca/xml?" + str_para + para_signature;
}

実際に実行してみると次のようなレスポンスが帰ってきます。

<?xml version="1.0"?>
<ItemLookupErrorResponse xmlns="http://ecs.amazonaws.com/doc/2009-01-06/">
  <Error>
    <Code>RequestExpired</Code>
    <Message>Request has expired. Timestamp date is 2009-01-01T12:00:00Z.</Message>
  </Error>
  <RequestID>760b74ee-d420-48d4-b771-f0c873222784</RequestID>
</ItemLookupErrorResponse>

現在固定の値として設定しているタイムスタンプが適当な値なので期限切れとなってます。

そこで「タイムスタンプの追加」で作成した関数を使って正しいタイムスタンプを設定します。

function getSignature(){
  var str_imestamp = getISO8601Timestamp();

  var para = {
    "Service":"AWSECommerceService",
    "AWSAccessKeyId":"00000000000000000000",
    "Operation":"ItemLookup",
    "ItemId":"0679722769",
    "ResponseGroup":"ItemAttributes,Offers,Images,Reviews",
    "Version":"2009-01-06",
    "Timestamp":str_imestamp
  };

  var para_array = [];

  for(var pname in para){
    para_array.push(pname + "=" + encodeURIComponent(para[pname]));
  }

  para_array.sort();

  var str_para = para_array.join('&');
  var str_signature = "GET" + "¥n" + "webservices.amazon.com" + "¥n" + "/onca/xml" + "¥n" + str_para;

  HMAC_SHA256_init("1234567890");
  HMAC_SHA256_write(str_signature);
  var array_hash = HMAC_SHA256_finalize();

  var str_hash = "";
  for (var i = 0; i < array_hash.length; i++) {
    str_hash += String.fromCharCode(array_hash[i]);
  }

  var signature = Base64.encode(str_hash);
  var para_signature = "&Signature=" + encodeURIComponent(signature);

  location.href = "http://webservices.amazon.com/onca/xml?" + str_para + para_signature;
}

function getISO8601Timestamp(){
  var d = new Date();

  var ye = d.getUTCFullYear();
  var mo = zeroPlus(d.getUTCMonth() + 1);
  var da = zeroPlus(d.getUTCDate());
  var ho = zeroPlus(d.getUTCHours());
  var mi = zeroPlus(d.getUTCMinutes());
  var se = zeroPlus(d.getUTCSeconds());

  return ye + "-" + mo + "-" + da + "T" + ho + ":" + mi + ":" + se + "Z";
}

function zeroPlus(value){
  return ("0" + value).slice(-2);
}

実際に実行してみると次のようなレスポンスが帰ってきます。

<?xml version="1.0"?>
<ItemLookupErrorResponse xmlns="http://ecs.amazonaws.com/doc/2009-01-06/">
  <Error>
    <Code>InvalidClientTokenId</Code>
    <Message>The AWS Access Key Id you provided does not exist in our records.</Message>
  </Error>
  <RequestID>c8cdb08e-8625-4a42-9282-37c9bed2b29f</RequestID>
</ItemLookupErrorResponse>

今度は「AWS Access Key」が存在しない値が使われていると出ます。そこで「AWSAccessKeyId」と秘密キーに実際の値を使用して再度試してみます。

署名をリクエストに追加

今度は無事リクエストが帰ってきました。

( Written by Tatsuo Ikura )