本文介绍了将JavaScript AJAX转换为Coinbase API,获取“请求时间戳过期”。使用服务器时间出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究一些代码,它们将调用

解决方案

引用:

您的时间戳以毫秒为单位,而不是秒。



如果我没记错的话,签名应该用十六进制而不是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,获取“请求时间戳过期”。使用服务器时间出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 09:21