从 GAS 请求 WebApp(在 GSheets 中)
Request WebApp from GAS (inside a GSheets)
过去几天我花了很多时间阅读有关我的主题的帖子,但我没有找到解决方案。
- A 创建了一个简单的(独立的)Web 应用程序来修改表格(本例中为 appendRow)。这个 WebApp 是作为我执行的,每个人都有访问权限:
function doGet(e) {
Logger.log("Call WebApi ok");
//var idSheet = e.parameter.idu;
var idSheet = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";
//Logger.log(idSheet);
var ss = SpreadsheetApp.openById(idSheet);
var sh = ss.getSheetByName('tab1');
sh.appendRow(["Test"]);
}
- 在 Google 表格中,我创建了(调用者)脚本。
function go() {
var url = "https://script.google.com/a/AAAAA/macros/s/XXXXXXXXXXXXXXXX/exec";
var params = {
method: "get",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
};
UrlFetchApp.fetch(url,params);
}
调用者脚本在清单中具有以下作用域:
"oauthScopes": ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/spreadsheets"]
-> 如果我使用与 WebApp 所有者不同的帐户执行调用者脚本,则它不起作用。
我收到 403 错误。
-> 但是,如果我在 Chrome 中打开 Publish WebApp 的 URL,它会起作用!
您知道为什么表格中的调用者脚本无法使用它吗?
谢谢!
路易斯
我测试了您的代码,调用者脚本在以 WebApp 所有者或任何其他帐户执行时运行良好。它失败的唯一场景是在隐身模式下执行时(某些 Google 应用程序脚本函数在隐身模式下表现得很奇怪)。
尽量不要以隐身方式执行它,或者因为您没有使用 getOAuthToken 更改您的 go() 函数,如下所示
function go() {
UrlFetchApp.fetch("https://script.google.com/a/AAAAA/macros/s/XXXXXXXXXXXXXXXX/exec");
}
如果您的 WebApp 是公开部署的,您不需要提供授权headers来获取 WebApp,您也不需要提供 oauth 范围。
但是,如果从脚本调用 WebApp - 在隐身模式下,将其部署为“任何人都可以访问”是不够的。
您需要将其发布为“任何人,甚至是匿名的”。
更新
如果发布您的 WebApp 以访问“任何人,甚至匿名”对您来说不是一个可接受的解决方案,并且从浏览器中调用 WebApp,您需要实施不同的方法。
为了实施只应为您的域授权的请求,最合适的解决方案是使用 service account with domain-wide delegation。
这意味着:
- 不要创建 WebApp
- 在用户调用的脚本中实现 WebApp 当前包含的代码
- 如果您创建一个服务帐户并允许 domain-wide 委派,这意味着您域中的任何用户都可以代表您执行请求(您授权范围)——无需WebApp 的。
- 要在 Google Apps 脚本中实施服务帐户,您需要使用 apps-script-oauth2 library
- 有关实施示例,请参阅 here
过去几天我花了很多时间阅读有关我的主题的帖子,但我没有找到解决方案。
- A 创建了一个简单的(独立的)Web 应用程序来修改表格(本例中为 appendRow)。这个 WebApp 是作为我执行的,每个人都有访问权限:
function doGet(e) {
Logger.log("Call WebApi ok");
//var idSheet = e.parameter.idu;
var idSheet = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";
//Logger.log(idSheet);
var ss = SpreadsheetApp.openById(idSheet);
var sh = ss.getSheetByName('tab1');
sh.appendRow(["Test"]);
}
- 在 Google 表格中,我创建了(调用者)脚本。
function go() {
var url = "https://script.google.com/a/AAAAA/macros/s/XXXXXXXXXXXXXXXX/exec";
var params = {
method: "get",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
};
UrlFetchApp.fetch(url,params);
}
调用者脚本在清单中具有以下作用域:
"oauthScopes": ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/spreadsheets"]
-> 如果我使用与 WebApp 所有者不同的帐户执行调用者脚本,则它不起作用。 我收到 403 错误。
-> 但是,如果我在 Chrome 中打开 Publish WebApp 的 URL,它会起作用!
您知道为什么表格中的调用者脚本无法使用它吗?
谢谢! 路易斯
我测试了您的代码,调用者脚本在以 WebApp 所有者或任何其他帐户执行时运行良好。它失败的唯一场景是在隐身模式下执行时(某些 Google 应用程序脚本函数在隐身模式下表现得很奇怪)。
尽量不要以隐身方式执行它,或者因为您没有使用 getOAuthToken 更改您的 go() 函数,如下所示
function go() {
UrlFetchApp.fetch("https://script.google.com/a/AAAAA/macros/s/XXXXXXXXXXXXXXXX/exec");
}
如果您的 WebApp 是公开部署的,您不需要提供授权headers来获取 WebApp,您也不需要提供 oauth 范围。
但是,如果从脚本调用 WebApp - 在隐身模式下,将其部署为“任何人都可以访问”是不够的。
您需要将其发布为“任何人,甚至是匿名的”。
更新
如果发布您的 WebApp 以访问“任何人,甚至匿名”对您来说不是一个可接受的解决方案,并且从浏览器中调用 WebApp,您需要实施不同的方法。
为了实施只应为您的域授权的请求,最合适的解决方案是使用 service account with domain-wide delegation。
这意味着:
- 不要创建 WebApp
- 在用户调用的脚本中实现 WebApp 当前包含的代码
- 如果您创建一个服务帐户并允许 domain-wide 委派,这意味着您域中的任何用户都可以代表您执行请求(您授权范围)——无需WebApp 的。
- 要在 Google Apps 脚本中实施服务帐户,您需要使用 apps-script-oauth2 library
- 有关实施示例,请参阅 here