【问题标题】:Xero API Auth fails using query string using Google Apps ScriptXero API Auth 使用 Google Apps 脚本使用查询字符串失败
【发布时间】:2016-08-05 13:19:38
【问题描述】:

我已成功使用 Xero API 授权我的 Google Apps Script 应用程序,并且可以获得试算表。但是,一旦我将查询字符串 (?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

【问题讨论】:

标签: google-apps-script xero-api


【解决方案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

【讨论】:

  • 哇!谢谢。不要以为我会解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 2014-08-05
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
相关资源
最近更新 更多