使用GAS的Xero API签名无效

时间:2019-09-03 14:19:32

标签: google-apps-script xero-api

我正在使用Google Apps脚本访问API。我正在寻找https://developer.xero.com/documentation/api/reports#TrialBalance

我已经尝试使用API​​代码,但是我收到签名无效作为回赠结果[19-09-03 19:45:46:402 IST] oauth_problem = signature_invalid&oauth_problem_advice = Failed%20to%20validate%20signature

function doGet(e) {
    getTrialBalances();
}

function getTrialBalances() {
    var oauth_nonce = createGuid();
    var oauth_timestamp = (new Date().valueOf() / 1000).toFixed(0);
    var CONSUMER_KEY = 'B7D5YA8D1HWHUZIGXL1AZS44N'
    var PEM_KEY = '-----BEGIN RSA PRIVATE KEY-----' +
        'ANIICXAIBAAKBgQC2WiSrkljVAZIgNUe/nBZ+PGJzauBJ6szlzPow1XoySkVikswui1IX4wUzgLmvnCmnQkRPgA43oiZqmK1H68MvirYzQkMa3sETViQAOiRPOrDEUTkemKiDXpaIKedD8T6/P9qzgtgU5hlP/R45POanIuNFvYPdpkm2yybOmI+1TwIjAQABAoGADt/3kc9UU7vXEa2G9shixVVjqoqTVTREFpLL7ePcHfIVCt9yrHFM9wnbyMG9uRZRIyDmbpumClROJImuADxc6reamXdTMX0OwEPogAREnY2diadjVjicoMYYEcdbb6pgDSOWcYtamNmzD5tkPI0bPFU+fTdpzGCOCECQQDvZTha0SRcCZPZipCs7PtAOWtMP1FBe140+cvsWiq2eHMmYDtIi7Mx210i3wzz4+Izl4jXeICKprppaBlJxSFZAkEAwwALfSnpqWeop86nnUICOPmksbK2rTtNVd+WGiAK4reUDJArOOXdDm7fYqppQNA35hxcRmvxeKK7jSYLQYHO5wJAeLFubRL+IszNVqLud9Buh52rQ+C0RbA9+bVqozl+SUqGu3VOzi9oY5114kvUCu38MAiY/BELtVuDpfrOrQuO2QJAHrZZGOOLC8VpyNRBjgEhfHvFNr+hCfO3IHlQmNjHHiIvzTK/u/xoLqfDwzR30194DmQVHHpP0+I9i+OcDjs1rQJBAJMY6h4QdYSFpTPxUOPA/s1lKVvJUIzgzX6oMfvc4TDb0RCz4nCvjJ1NEqPjveB6ze5TzC8BzfRW/aUh49vmgRA=' +
        '-----END RSA PRIVATE KEY-----';

    var payload = '';

    var URL = 'https://api.xero.com/api.xro/2.0/Reports/TrialBalance';
    var signatureBase = "GET" + "&" +
        encodeURIComponent(URL) + "&" +
        encodeURIComponent('date=2019-02-01') + "&" +
        encodeURIComponent("oauth_consumer_key=" + CONSUMER_KEY +
            "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=RSA-SHA1&oauth_timestamp=" +
            oauth_timestamp + "&oauth_token=" + CONSUMER_KEY + "&oauth_version=1.0");
    var rsa = new RSAKey();
    rsa.readPrivateKeyFromPEMString(PEM_KEY);
    var hashAlg = "sha1";
    var hSig = rsa.signString(signatureBase, hashAlg);

    var oauth_signature = encodeURIComponent(hextob64(hSig));

    var authHeader = "OAuth oauth_token=\"" + CONSUMER_KEY + "\",oauth_nonce=\"" + oauth_nonce +
        "\",oauth_consumer_key=\"" + CONSUMER_KEY + "\",oauth_signature_method=\"RSA-SHA1\",oauth_timestamp=\"" +
        oauth_timestamp + "\",oauth_version=\"1.0\",oauth_signature=\"" + oauth_signature + "\"";
    var headers = {
        "Authorization": authHeader,
        "Accept": "application/json"
    };
    var options = {
        "headers": headers,
        'method': 'GET',
        'payload': payload,
        'muteHttpExceptions': true,
    };

    var requestURL = URL + '?date=2019-02-01';
    var response = UrlFetchApp.fetch(requestURL, options);
    var responseXml = response.getContentText();
    Logger.log(responseXml);
}

function createGuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0,
            v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16)
    });
}

对于RSA签名,我使用了https://github.com/csi-lk/google-app-script-xero-api/blob/master/jsrsasign.gs

更新2:

我对此进行了编码,但仍然无法获得结果

var signatureBase = encodeURIComponent("GET" + "&" + URL + "&" + 'date=2019-02-01' + "&" + "oauth_consumer_key=" + CONSUMER_KEY +
            "&oauth_nonce=" + oauth_nonce + "&oauth_signature_method=RSA-SHA1&oauth_timestamp=" +
            oauth_timestamp + "&oauth_token=" + CONSUMER_KEY + "&oauth_version=1.0");

1 个答案:

答案 0 :(得分:2)

在阅读我的其余答案之前,请先紧急重置您的应用程序使用者密钥/机密,以及根据问题的提供情况创建新的公共证书并将其上传到开发者门户。 / strong>


您遇到的至少一个我能发现的问题是如何构建签名基本字符串。

仅应将初始的保留为未编码状态,但是应将签名基本字符串中的其余部分进行编码。保留未编码的URL和编码的日期查询参数后,它看起来像

编辑: 以下两行省略了&s ouf编码,但需要将它们包含在uri编码中

encodeURIComponent(URL) + "&" +
encodeURIComponent('date=2019-02-01') + "&" +