Xero API Auth 使用 Google Apps 脚本使用查询字符串失败
Xero API Auth fails using query string using Google Apps Script
我已成功使用 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
您的问题会在这个阶段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
您需要将查询参数字符串拆分为两个参数,然后sort/add它们相应地
date=YYYY-mm-dd&oauth_consumer_key=blah&...&oauth_version=1.0&page=1
我已成功使用 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
您的问题会在这个阶段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
您需要将查询参数字符串拆分为两个参数,然后sort/add它们相应地
date=YYYY-mm-dd&oauth_consumer_key=blah&...&oauth_version=1.0&page=1