Мне действительно трудно понять поведение js.
var rp = require('request-promise');
var crypto = require('crypto');
var options = {
method : 'GET',
uri : "https://api.binance.com/api/v1/order",
qs: {
signature : hash,
timestamp : Date.now(),
symbol : 'LTCBTC'
},
headers: {
'X-MBX-APIKEY' : 'PUBLICKEY'
},
json : true
};
var hash= crypto.createHmac('sha256', options.toString())
.update('SECRETKEY')
.digest('hex');
//console.log(hash);
rp(options)
.then(function (Bbody) {
console.log(Bbody);
})
.catch(function (err) {
console.log(err);
});
если я возьму hash
функцию и поставлю ее перед options
он говорит (очевидно)
TypeError: Невозможно прочитать свойство 'toString' неопределенного
но если я поместил его как в код, который я разделял, я получаю эту ошибку:
StatusCodeError: 400 - {"code": -1102, "msg": "Обязательный параметр" подпись "не был отправлен, был пустым/нулевым или искаженным."}
и это результат запроса:
options:
{ method: 'GET',
uri: 'https://api.binance.com/api/v1/order',
qs:
{ signature: undefined,
timestamp: 1540392736646,
symbol: 'LTCBTC' },
headers:
{ 'X-MBX-APIKEY':
'PUBLICKEY' },
json: true,
callback: [Function: RP$callback],
transform: undefined,
simple: true,
resolveWithFullResponse: false,
transform2xxOnly: false },
Если я раскомментирую console.log()
я получаю правильный хеш, напечатанный на видео, как первый вывод, перед отклонением запроса. Тем не менее вызов не может его поймать.
Я использовал как документы:
эта документация узла для криптографической библиотеки
и этот npm doc, чтобы обещать вызовы api
PS: PUBLICKEY
и SECRETKEY
являются заполнителями, но в моих тестах я использовал правильные строки.
Там что-то называется переменной подъема в JavaScript. В принципе, JavaScript тайно перемещает объявление вашей hash
переменной в начало скрипта как var hash;
, Когда вы создаете переменную options
, hash
еще не определен.
Помимо переменной подъема, я не думаю, что вы сможете генерировать хэш объекта JavaScript, который должен содержать в себе то же самое значение хэша. Согласно https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#signed-endpoint-examples-for-post-apiv1order, вам необходимо принять следующие шаги:
symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=5000×tamp=1499827319559
https://api.binance.com/api/v3/order?symbol=LTCBTC&side=BUY&type=LIMIT&...&signature=<your sha256 here>
)&
symbol
или timestamp
и после этого вы добавляете другой параметр запроса, называемый signature
где вы предоставляете хэш.
crypto.createHmac(algorithm, key[, options])
вам все еще нужен ключ, опции - это необязательный параметр, а выполнениеoptions.toString()
не вернет вам строковое значение. Вы хотите исправить свой код, просто добавив дополнительный параметр:var hash= crypto.createHmac('sha256', 'secretkeytoken', options)