Xero API Auth无法使用Google Apps脚本使用查询字符串

时间:2016-08-05 13:19:39

标签: google-apps-script xero-api

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

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

任何人都可以看到问题:

The Gist

  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

1 个答案:

答案 0 :(得分:1)

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

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

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

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

在您的查询参数示例

?date=YYYY-mm-dd 

以及如何创建签名基本字符串,最后将使用查询参数,而应该是第一个。

date=... < oauth_consumer_key=...

它为您的分页参数正常工作的原因很方便,&#39; page = ...&#39;将是排序后添加的最后一个参数。

如果您的查询参数字符串是

,也值得注意
?page=1&date=YYYY-mm-dd

您需要将查询参数字符串拆分为两个参数并按顺序排序/添加

date=YYYY-mm-dd&oauth_consumer_key=blah&...&oauth_version=1.0&page=1