Google Web 应用程序 - 获取用户电子邮件,但 运行 脚本作为所有者
Google Web Apps - Get user email but run scripts as owner
我最近被 google 网络应用所吸引,但我有点进退两难。我正在尝试构建一个对非常特定的用户开放的应用程序,并且他们正在查看的数据会根据他们的访问组进行过滤。
在 google sheet 中,我列出了用户电子邮件及其各自的访问组。 A 列 - 电子邮件,B 列 - 访问组
问题
当用户访问网络应用程序时,我正在使用它来获取他们的电子邮件:
var email = Session.getActiveUser().getEmail();
然后我运行此代码获取他们的访问组:
function validate(email){
var sheet = SpreadsheetApp.openById(ID).getSheetByName(ssUserList);
try{
var group = getRowsData(sheet).find(e => e.userEmail === email).securityGroup;
return group;
} catch(e){
return "Not Authorized";
}
}
因为用户无权访问我的 google sheet,他们在函数 运行s 时收到错误消息。而且我无法像我一样将 Web 应用程序部署到 运行,因为我需要用户的电子邮件。这个我很明白。
我读过的内容:
关于访问令牌和凭据以及 urlFetchApps 的大量其他帖子和文章......我一点都不明白,老实说,我不知道哪一个更适合我的情况。
我试过的:
我无法使用我发现的第一个可用选项,即 访问网络应用程序 1(运行 作为用户),然后使用该用户调用网络应用程序 2电子邮件作为参数,因为如果他们从 Web 应用程序 2 共享 link,那么任何人都可以看到数据,而我正在处理非常敏感的数据。
我意识到我可以将这些参数放在一个单独的 sheet 中并给它们仅查看访问权限,脚本将 运行 正常,但我是额外的,我想做对.
实际上,我将有一些其他功能需要像我一样 运行。如果你处在我的位置,你会从哪里开始?或者有人可以通俗地解释一下吗?我应该研究 之类的东西吗?感谢您的帮助!
总结
如 所建议,其中一种可能性是创建一个单独的 Web 应用程序来处理对 SpreadSheets 的访问。
客户端(主要网络应用程序)将通过 UrlFetchApp
向中间件(负责查询 SpreadSheet 的网络应用程序)发出请求,中间件将进行所需的查询并 return 他们给客户。最后,根据获得的响应,将呈现一个内容或另一个内容。
最小示例
配置项目
首先,我们创建两个 GAS 项目,一个称为 Main,另一个称为 Middleware。要点是中间件将 运行 作为 USER_DEPLOYING
,而客户端将作为 USER_ACCESSING
。这允许访问 sheet 而无需额外的权限。
appscripts.json
文件在客户端上看起来像这样。 :
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/userinfo.email"
],
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "ANYONE"
}
在中间件上像这样:
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets"
],
"webapp": {
"executeAs": "USER_DEPLOYING",
"access": "ANYONE_ANONYMOUS"
}
如果您对编辑或查看 appscript.json
有任何疑问,请查看 Manifest and Scopes 文档。
注意:"access": "ANYONE"
和"access": "ANYONE_ANONYMOUS"
仅用于测试目的。这很危险,应根据项目的特定需求进行审查。
代码示例
对于client,我们只需要通过Session.getActiveUser().getEmail()
获取正在访问的用户的email,然后发送给中间件就可以得到response。根据获得的响应,我们将呈现一个或另一个内容(我假设存在两个角色:USER
和 ADMIN
)
客户
const doGet = () => {
var data = {email: Session.getActiveUser().getEmail()}
var options = {
'method': 'POST',
'contentType': 'application/json',
'payload': JSON.stringify(data)
}
var fetch = UrlFetchApp.fetch(URL_MIDDLEWARE, options)
var userAccess = JSON.parse(fetch).accessLevel
return HtmlService.createHtmlOutput(
userAccess === "ADMIN"
? `<h1>${data.email} - ADMIN USER</h1>`
: userAccess === "USER"
? `<h1>${data.email} - COMMON USER</h1>`
: "<h1>Unauthorized</h1>" )
}
对于中间件,我们需要获取该电子邮件并将其与我们的 sheet 进行比较以检查用户的访问级别。然后我们return结果。
中间件
const doPost = (request) => {
// destructuring the request
const { parameter, postData: { contents, type } = {} } = request;
const userEmail = JSON.parse(contents).email;
let userAccess = SpreadsheetApp.openById(SPREADSHEET_ID).getRange('A1:B2').getValues()
// This can be replaced by a filter function
let userAccessLevel;
for (let user of userAccess) { if (userEmail == user[0]) userAccessLevel = user[1] }
return ContentService.createTextOutput(Utilities.jsonStringify({
user: userEmail,
accessLevel: userAccessLevel
}))
};
最后,您访问主 Web 应用程序以检查一切是否正常。
请记住,这是一个测试实施,不应在生产中使用。如果您需要有关这些主题的更多信息,可以访问以下链接:
我最近被 google 网络应用所吸引,但我有点进退两难。我正在尝试构建一个对非常特定的用户开放的应用程序,并且他们正在查看的数据会根据他们的访问组进行过滤。
在 google sheet 中,我列出了用户电子邮件及其各自的访问组。 A 列 - 电子邮件,B 列 - 访问组
问题
当用户访问网络应用程序时,我正在使用它来获取他们的电子邮件:
var email = Session.getActiveUser().getEmail();
然后我运行此代码获取他们的访问组:
function validate(email){
var sheet = SpreadsheetApp.openById(ID).getSheetByName(ssUserList);
try{
var group = getRowsData(sheet).find(e => e.userEmail === email).securityGroup;
return group;
} catch(e){
return "Not Authorized";
}
}
因为用户无权访问我的 google sheet,他们在函数 运行s 时收到错误消息。而且我无法像我一样将 Web 应用程序部署到 运行,因为我需要用户的电子邮件。这个我很明白。
我读过的内容:
关于访问令牌和凭据以及 urlFetchApps 的大量其他帖子和文章......我一点都不明白,老实说,我不知道哪一个更适合我的情况。
我试过的:
我无法使用我发现的第一个可用选项,即 访问网络应用程序 1(运行 作为用户),然后使用该用户调用网络应用程序 2电子邮件作为参数,因为如果他们从 Web 应用程序 2 共享 link,那么任何人都可以看到数据,而我正在处理非常敏感的数据。
我意识到我可以将这些参数放在一个单独的 sheet 中并给它们仅查看访问权限,脚本将 运行 正常,但我是额外的,我想做对.
实际上,我将有一些其他功能需要像我一样 运行。如果你处在我的位置,你会从哪里开始?或者有人可以通俗地解释一下吗?我应该研究
总结
如
客户端(主要网络应用程序)将通过 UrlFetchApp
向中间件(负责查询 SpreadSheet 的网络应用程序)发出请求,中间件将进行所需的查询并 return 他们给客户。最后,根据获得的响应,将呈现一个内容或另一个内容。
最小示例
配置项目
首先,我们创建两个 GAS 项目,一个称为 Main,另一个称为 Middleware。要点是中间件将 运行 作为 USER_DEPLOYING
,而客户端将作为 USER_ACCESSING
。这允许访问 sheet 而无需额外的权限。
appscripts.json
文件在客户端上看起来像这样。 :
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/userinfo.email"
],
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "ANYONE"
}
在中间件上像这样:
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets"
],
"webapp": {
"executeAs": "USER_DEPLOYING",
"access": "ANYONE_ANONYMOUS"
}
如果您对编辑或查看 appscript.json
有任何疑问,请查看 Manifest and Scopes 文档。
注意:"access": "ANYONE"
和"access": "ANYONE_ANONYMOUS"
仅用于测试目的。这很危险,应根据项目的特定需求进行审查。
代码示例
对于client,我们只需要通过Session.getActiveUser().getEmail()
获取正在访问的用户的email,然后发送给中间件就可以得到response。根据获得的响应,我们将呈现一个或另一个内容(我假设存在两个角色:USER
和 ADMIN
)
客户
const doGet = () => {
var data = {email: Session.getActiveUser().getEmail()}
var options = {
'method': 'POST',
'contentType': 'application/json',
'payload': JSON.stringify(data)
}
var fetch = UrlFetchApp.fetch(URL_MIDDLEWARE, options)
var userAccess = JSON.parse(fetch).accessLevel
return HtmlService.createHtmlOutput(
userAccess === "ADMIN"
? `<h1>${data.email} - ADMIN USER</h1>`
: userAccess === "USER"
? `<h1>${data.email} - COMMON USER</h1>`
: "<h1>Unauthorized</h1>" )
}
对于中间件,我们需要获取该电子邮件并将其与我们的 sheet 进行比较以检查用户的访问级别。然后我们return结果。
中间件
const doPost = (request) => {
// destructuring the request
const { parameter, postData: { contents, type } = {} } = request;
const userEmail = JSON.parse(contents).email;
let userAccess = SpreadsheetApp.openById(SPREADSHEET_ID).getRange('A1:B2').getValues()
// This can be replaced by a filter function
let userAccessLevel;
for (let user of userAccess) { if (userEmail == user[0]) userAccessLevel = user[1] }
return ContentService.createTextOutput(Utilities.jsonStringify({
user: userEmail,
accessLevel: userAccessLevel
}))
};
最后,您访问主 Web 应用程序以检查一切是否正常。
请记住,这是一个测试实施,不应在生产中使用。如果您需要有关这些主题的更多信息,可以访问以下链接: