从Google Apps脚本到BitStamp API的API0005无效的签名连接错误

时间:2019-06-08 16:44:12

标签: javascript api google-apps-script google-sheets nonce

我正在尝试将我的BitStamp帐户中的不同信息显示到Google Spreadsheet上。 为了做到这一点,使用了Google Apps脚本(GAS),当然还有Javascript。

我得到的错误是API0005,as you can see from BitStamp API reference page代表无效签名:

  

API0005签名无效张贴的签名与我们的不匹配

现在,我一直在从多个来源收集信息,尤其是在Stack上,但是我还不太清楚问题出在哪里。

尽管如此,我还是要强调一点,因为我想问题可能与之有关:

为了便于构造,我通常将签名综合过程的主要步骤附加到电子表格本身,以便对它的开发有更好的了解。

每次以某种方式调用或调用函数时,即使在一行代码与下一行代码之间,您也会注意到 nonce 输出中的细微变化;这并不令我感到惊讶,因为我想每次调用nonce都需要经过几毫秒,并且输出必须是不同的(毕竟我是出于这个原因而故意设计的)。

但是我首先要担心的是:即使调用toUpperCase()转换,它也可以更改吗? (顺便说一句,我猜这也不应该是问题的原因)

Spreadsheet Cells Screenshot

var nonce = new (function() {
    this.generate = function() {
        var now = Date.now();
        this.counter = (now === this.last? this.counter + 1 : 0);
        this.last    = now;
        // add padding to nonce
        var padding = 
            this.counter < 10 ? '000' : 
                this.counter < 100 ? '00' :
                    this.counter < 1000 ?  '0' : '';
        return now+padding+this.counter;
    };
})();

//funzione write
function write() {

var cred = {
       id:'digit2118',
      key:'2RhZfUKIYJbT8CBYk6T27uRSF8Gufre',
   secret:'T8CBYk6T274yyR8Z2RhZfUxbRbmZZHJ'
};

//adding some cells output to monitor each step of the "conversion" 
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange("B14");
cell.setValue(cred.id);
// .. and so on, see screen cap..

var message = nonce.generate() + cred.id +  cred.key;

var res = Utilities.computeHmacSha256Signature(cred.secret, message).map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join("");
var signature = res.toUpperCase();

// qui mettiamo i dati per fare la comunicazione vera e propria
var data = {
  key: cred.key,
  signature: res,
  nonce: nonce.generate()
};

var options = {
  'method' : 'post',
  //'contentType': 'application/json',
  // Convert the JavaScript object to a JSON string.
  //'payload' : JSON.stringify(data)
  'muteHttpExceptions' : true,
  'payload' : data
};

var risposta = UrlFetchApp.fetch('https://www.bitstamp.net/api/v2/balance/', options);
  var risposta2 = JSON.parse(risposta.getContentText());

  Logger.log(risposta2);
  //Logger.log(risposta.getContentText()); 
return signature;
}//end of write();

Logger.log(write());

所以最终我看不到哪里,但这一定是我所缺少的。

(ps:这是我从Generate Nonce处获得Nonce代码的地方)

编辑:问题已解决

更新的代码,下面有问题和解决方案。

感谢@Tanaike

2 个答案:

答案 0 :(得分:1)

此修改如何?

修改点:

  • Utilities.computeHmacSha256Signature(value, key)的自变量中,依次为valuekey
    • 请将Utilities.computeHmacSha256Signature(cred.secret, message)修改为Utilities.computeHmacSha256Signature(message, cred.secret)

修改后的脚本:

从:
var res = Utilities.computeHmacSha256Signature(cred.secret, message).map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join("");
至:
var res = Utilities.computeHmacSha256Signature(message, cred.secret).map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join("");

注意:

  • 如果上述修改后发生错误,请在请求中将nonce固定为常量,然后重试。
    • 我认为nonce可能需要在请求中固定。为此,请在您的环境中进行测试。
    • 因为当我看到a sample script for Node.js时,nonce在请求中被固定为常量值。

参考:

我无法在我的环境中测试此修改。因此,如果这不是您问题的直接解决方案,对不起。如果此修改更改了错误消息,也请提供它。

答案 1 :(得分:0)

在结合@Tanaike提供的明智建议后,即在value命令中正确切换keyUtilities.computeHmacSha256Signature(value, key),事情还没有开始,我仍然习惯了无效的签名API0005错误。

长话短说,问题是代码中的另一个疏忽:

我正确地将签名切换为toUpperCase(),但是在将数组发送到BitStamp时,我曾经发送的是小写版本,即res而不是signature

var signature = res.toUpperCase();

// qui mettiamo i dati per fare la comunicazione vera e propria
var data = {
  key: cred.key,
  signature: res,
  nonce: nonce.generate()
};

细节已经修复,现在可以正常使用! 这是完整且更新的工作代码,供您考虑:

//funzione write
function write() {

/* nuova funzione nonce */
_generateNonce = function() {
  var now = new Date().getTime();

  if(now !== this.last)
    this.nonceIncr = -1;

  this.last = now;
  this.nonceIncr++;

  // add padding to nonce incr
  // @link https://stackoverflow.com/questions/6823592/numbers-in-the-form-of-001
  var padding =
    this.nonceIncr < 10 ? '000' :
      this.nonceIncr < 100 ? '00' :
        this.nonceIncr < 1000 ?  '0' : '';
  return now + padding + this.nonceIncr;
}

 var nonce = this._generateNonce(); //fine funzione

var cred = {
       id:'digit2118',
      key:'2RhZfUKIYJbT8CBYk6T27uRSF8Gufrer',
   secret:'T8CBYk6T274yyR8Z2RhZfUxbRbmZZHJr'
};

var message = nonce + cred.id +  cred.key;

var res = Utilities.computeHmacSha256Signature(message, cred.secret).map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join("");

var signature = res.toUpperCase();

var data = {
  key: cred.key,
  signature: signature,
  nonce: nonce
};

var options = {
  'method' : 'post',
  //'contentType': 'application/json',
  // Convert the JavaScript object to a JSON string.
  //'payload' : JSON.stringify(data)
  'muteHttpExceptions' : true,
  'payload' : data
};

var risposta = UrlFetchApp.fetch('https://www.bitstamp.net/api/v2/balance/', options);
  var risposta2 = JSON.parse(risposta.getContentText());
  var risposta3 = risposta2['usd_balance'];
  Logger.log(risposta3);
return signature;
}//end of write();