我正在尝试将我的BitStamp帐户中的不同信息显示到Google Spreadsheet上。 为了做到这一点,使用了Google Apps脚本(GAS),当然还有Javascript。
我得到的错误是API0005,as you can see from BitStamp API reference page代表无效签名:
API0005签名无效张贴的签名与我们的不匹配
现在,我一直在从多个来源收集信息,尤其是在Stack上,但是我还不太清楚问题出在哪里。
尽管如此,我还是要强调一点,因为我想问题可能与之有关:
为了便于构造,我通常将签名综合过程的主要步骤附加到电子表格本身,以便对它的开发有更好的了解。
每次以某种方式调用或调用函数时,即使在一行代码与下一行代码之间,您也会注意到 nonce 输出中的细微变化;这并不令我感到惊讶,因为我想每次调用nonce
都需要经过几毫秒,并且输出必须是不同的(毕竟我是出于这个原因而故意设计的)。>
但是我首先要担心的是:即使调用toUpperCase()
转换,它也可以更改吗?
(顺便说一句,我猜这也不应该是问题的原因)
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
答案 0 :(得分:1)
此修改如何?
Utilities.computeHmacSha256Signature(value, key)
的自变量中,依次为value
和key
。
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
可能需要在请求中固定。为此,请在您的环境中进行测试。nonce
在请求中被固定为常量值。我无法在我的环境中测试此修改。因此,如果这不是您问题的直接解决方案,对不起。如果此修改更改了错误消息,也请提供它。
答案 1 :(得分:0)
在结合@Tanaike提供的明智建议后,即在value
命令中正确切换key
和Utilities.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();