问题描述
我一直在研究一些代码,它们将调用
引用:
您的时间戳以毫秒为单位,而不是秒。
如果我没记错的话,签名应该用十六进制而不是base64编码():
var hash = CryptoJS.HmacSHA256(message,LOGIN_DATA.Coinbase .apiSecret);
var hexDigest = hash.toString(CryptoJS.enc.Hex)
I've been working on some code that will call the List Accounts call from the Coinbase API. I am using the API Key to authenticate and CryptoJSv3.1.2 to handle the encryption. I believe that I am correctly signing my request but I haven't done a lot of encryption in JavaScript before so please double check my work.
The issue that I am having is that my request for accounts is being rejected and the message I'm getting back from Coinbase is {"errors":[{"id":"authentication_error","message":"request timestamp expired"}]}
I am aware the of the 30 second restriction for requests however I am using the Coinbase server time that I am getting back from the Get Current Time call. Also, the total run time for both calls is <1 second so my timestamp should be the current time. Any guidance would be very helpful. Thanks in advance.
Here is my code:
var LOGIN_DATA = {
Coinbase: {
apiKey: "XXXXXXXXXXXXXXXX",
apiSecret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
version: "2018-01-05"
}
}
var Coinbase = new (function(){
var cb = this;
var baseURL = "https://api.coinbase.com/v2";
this.listAccounts = function(){
var start = new Date();
var method = "GET";
var url = baseURL + "/accounts";
var header = buildRequestHeader(method, url);
var accounts = connect(method, url, header);
var finish = new Date();
console.debug("time elapsed: ", (finish.getTime() - start.getTime()))
return accounts;
}
function buildRequestHeader(method, url, data){
var timeStamp = getServerTime();
console.debug("timeStamp: ", timeStamp)
var header = {
"CB-ACCESS-KEY": LOGIN_DATA.Coinbase.apiKey,
"CB-ACCESS-SIGN": buildSignature(timeStamp, method, url, data),
"CB-ACCESS-TIMESTAMP": timeStamp
}
console.debug("header: ", header);
return header;
}
function buildSignature(timeStamp, method, requestPath, data){
var message = timeStamp + method.toUpperCase() + requestPath + (data == null ? "" : data)
console.debug("signature message: ", message);
var hash = CryptoJS.HmacSHA256(message, LOGIN_DATA.Coinbase.apiSecret);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
return hashInBase64
}
function getServerTime(){
var method = "GET"
var url = baseURL + "/time";
var onSuccess = function(data){
return (new Date(data.data.iso)).getTime();
}
return connect(method, url, null, null, onSuccess);
}
function connect(method, url, header, data, onSuccess, onError){
var rtn = null;
header = (header == null ? {} : header)
data = (data === null ? {} : data)
if(header["CB-VERSION"] === undefined){
header["CB-VERSION"] = LOGIN_DATA.Coinbase.version
}
console.debug("final header: ", header);
console.debug("final data: ", data);
$.ajax({
url: url,
type: method,
async: false,
timeout: 5000,
data: data,
beforeSend: function(xhr) {
for(var key in header){
xhr.setRequestHeader(key, header[key]);
}
},
success: function(data, textStatus, jqXHR) {
console.log("Coinbase connect successful: ", data);
if(!onSuccess){
onSuccess = function(data){ return data; }
}
rtn = onSuccess(data, textStatus, jqXHR);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error("Coinbase connect failed: ", textStatus, errorThrown, jqXHR);
if(onError){
rtn = onError(jqXHR, textStatus, errorThrown);
}
}
});
return rtn;
}
});
Also here is a screenshot of my console log statements incase they help:
Quoting the Coinbase API:
Your timestamp is in milliseconds, not seconds.
If I'm not mistaken the signature should be encoded in hex, not base64 (source):
var hash = CryptoJS.HmacSHA256(message, LOGIN_DATA.Coinbase.apiSecret);
var hexDigest = hash.toString(CryptoJS.enc.Hex)
这篇关于将JavaScript AJAX转换为Coinbase API,获取“请求时间戳过期”。使用服务器时间出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!