【问题标题】:Xero API signature invalid using GAS使用 GAS 的 Xero API 签名无效
【发布时间】:2019-09-03 14:19:32
【问题描述】:

我正在使用 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");

【问题讨论】:

    标签: google-apps-script xero-api


    【解决方案1】:

    在阅读我的其余答案之前,请您紧急重置您的应用程序消费者密钥/秘密,以及创建一个新的公共证书并将其上传到开发人员门户,正如您在问题中提供的那样。


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

    只有最初的 & 应该不编码,但是签名基本字符串中的其余部分应该被编码。看起来编码 URL 和编码日期查询参数之后的 & 未编码。

    编辑: 以下两行将 &s 排除在 ouf 编码之外,但它们需要包含在 uri 编码中

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

    【讨论】:

    • 我已经编辑了我的答案以显示我提到的问题
    • 在您的新 sn-p 中,您进入签名基本字符串的参数的顺序似乎已更改。即, oauth_token 已移至列表的前面。进入签名基本字符串的参数的顺序很重要。它们需要按字典顺序排列。简而言之,这意味着参数需要按字母顺序排列,首先是大写,然后是小写。请在此处查看我的答案以获取更多详细信息:stackoverflow.com/a/40335586/4878992
    • 你又改了,无视我原来的回答。第一个 & 不应该被编码。试试这个: var signatureBase = "GET&" + encodeURIComponent(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");
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2018-10-07
    相关资源
    最近更新 更多