0

我已使用 Xero API 成功授权我的 Google Apps Script 应用程序,并且可以获得试算表。但是,一旦我将查询字符串 (?date=YYYY-mm-dd) 添加到请求中,我会得到 401 - 未授权。

添加查询字符串的方式与我成功使用分页获取付款和发票的方式相同。

任何人都可以看到问题:

要点

  function getTrialBalancesWithNoDate() {

  // .
  // .
  // .

  fetchPublicAppData('Reports/TrialBalance', '', '') // OK

  // .
  // .
  // .
}

function getTrialBalancesWithDate() {

  // .
  // .
  // .

  fetchPublicAppData('Reports/TrialBalance', '2016-07-01', 'date') // Error - Not authorised

  // .
  // .
  // .
}

function getInvoices() {

  // .
  // .
  // .

  fetchPublicAppData('Invoices', pageNumber, 'page') // OK

  // .
  // .
  // .
}

function fetchPublicAppData(item, parameter, query) {  

  /* For PUBLIC APPLICATION TYPE */

  if (typeof query !== 'undefined' && query !== '') {
    query = query + '=' + parameter
  } else {
    query = ''
  }

  this.loadSettings(); // get latest settings

  var requestURL = API_END_POINT + '/' + item ;    
  var oauth_signature_method = 'HMAC-SHA1';
  var oauth_timestamp =  (new Date().getTime()/1000).toFixed();
  var oauth_nonce = Utils_.generateRandomString(Math.floor(Math.random() * 50));
  var oauth_version = '1.0';

  var signBase = 
      'GET' + '&' + 
        encodeURIComponent(requestURL) + '&' + 
          encodeURIComponent(
            'oauth_consumer_key=' + this.consumerKey + '&' + 
            'oauth_nonce=' + oauth_nonce + '&' + 
            'oauth_signature_method=' + oauth_signature_method + '&' + 
            'oauth_timestamp=' + oauth_timestamp + '&' + 
            'oauth_token=' + this.accessToken  + '&' +                             
            'oauth_version=' + oauth_version + (query === '' ? '' : '&') +              
            query);

  var sbSigned = Utilities
        .computeHmacSignature(
          Utilities.MacAlgorithm.HMAC_SHA_1, 
          signBase, 
          encodeURIComponent(this.consumerSecret) + '&' + encodeURIComponent(this.accessTokenSecret));

  var oauth_signature = Utilities.base64Encode(sbSigned);

  var authHeader = 
      "OAuth oauth_consumer_key=\"" + this.consumerKey + 
      "\",oauth_nonce=\"" + oauth_nonce + 
      "\",oauth_token=\"" + this.accessToken + 
      "\",oauth_signature_method=\"" + oauth_signature_method + 
      "\",oauth_timestamp=\"" + oauth_timestamp + 
      "\",oauth_version=\"1.0\",oauth_signature=\"" + 
      encodeURIComponent(oauth_signature) + "\"";

  var headers = {"User-Agent": + this.userAgent, "Authorization": authHeader, "Accept": "application/json"};
  var options = {"headers": headers, "muteHttpExceptions": false};

  requestURL = requestURL + (query === '' ? '' : '?') + query
  var response = UrlFetchApp.fetch(requestURL, options);
  var responseCode = response.getResponseCode();
  var responseText = response.getContentText();

  if (responseCode === 200) {

    return JSON.parse(responseText);

  } else if (responseCode === 401) {

    PropertiesService.getScriptProperties().setProperty('isConnected', 'false')
    onOpen() // Reset menu
    throw new Error('The Auth token has expired, run Xero > Settings (connect)');

  } else {

    throw new Error(responseText);
  }

} // fetchPublicAppData()enter code here
4

1 回答 1

1

您的问题将在此阶段https://gist.github.com/andrewroberts/fed16cc1c7fed9c6d805ffd077efe8c7#file-trialbalance-gs-L58-L68

在为 oauth 1.0a 构建 SignatgureBaseString 时,参数的顺序很重要。它们必须按字典顺序排列。

A, B ... Y, Z, a, b ... y, z 

简而言之,这意味着参数需要按字母顺序排列,首先是大写,然后是小写。

在您使用查询参数的示例中

?date=YYYY-mm-dd 

以及如何创建签名基本字符串,您最终会得到查询参数,而它应该是第一个。

date=... < oauth_consumer_key=...

它对您的分页参数正常工作的原因就是方便,'page=...' 将是排序后添加的最后一个参数。

还值得注意的是,如果您的查询参数字符串是

?page=1&date=YYYY-mm-dd

您需要将查询参数字符串拆分为两个参数并相应地对它们进行排序/添加

date=YYYY-mm-dd&oauth_consumer_key=blah&...&oauth_version=1.0&page=1
于 2016-10-31T01:49:15.043 回答