我一直在处理一些代码,这些代码会调用Coinbase API的List Accounts调用。我使用API Key进行身份验证,CryptoJSv3.1.2来处理加密。我相信我正确地签署了我的请求,但我还没有在JavaScript中进行过大量加密,所以请仔细检查我的工作。
我遇到的问题是我的帐户请求被拒绝了,而且我从Coinbase收到的消息是{"errors":[{"id":"authentication_error","message":"request timestamp expired"}]}
我知道请求的30秒限制,但是我使用的是Coinbase服务器时间,我从Get Current Time调用回来了。此外,两个呼叫的总运行时间<1秒,因此我的时间戳应该是当前时间。任何指导都会非常有帮助。提前谢谢。
这是我的代码:
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;
}
});
答案 0 :(得分:1)
引用Coinbase API:
CB-ACCESS-TIMESTAMP标头必须是自Unix Epoch以来的秒数。
您的时间戳以毫秒为单位,而不是秒。
如果我没弄错,签名应该用十六进制编码,而不是base64(source):
var hash = CryptoJS.HmacSHA256(message, LOGIN_DATA.Coinbase.apiSecret);
var hexDigest = hash.toString(CryptoJS.enc.Hex)