Niy*_*iya 2 google-apps-script google-sheets-api
我最近迷上了谷歌网络应用程序,但我遇到了一些进退两难的问题。我正在尝试构建一个对非常特定的用户开放的应用程序,并且他们正在查看的数据根据其访问组进行过滤。
在谷歌表格中,我列出了用户电子邮件及其各自的访问组。A 列 - 电子邮件,B 列 - 访问组
问题
当用户访问网络应用程序时,我使用它来获取他们的电子邮件:
var email = Session.getActiveUser().getEmail();
Run Code Online (Sandbox Code Playgroud)
然后我运行此代码来获取他们的访问组:
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";
}
}
Run Code Online (Sandbox Code Playgroud)
由于用户无权访问我的谷歌工作表,因此在函数运行时他们会收到错误。而且我无法部署 Web 应用程序以我的身份运行,因为我需要用户的电子邮件。我很明白这一点。
我读过的内容:
关于访问令牌和凭据以及 urlFetchApps 的大量其他帖子和文章......我不理解其中任何一个,说实话,我不知道哪一个对我的情况更有意义。
我尝试过的:
我无法使用我发现的第一个可用选项,即访问Web 应用程序 1(以用户身份运行),然后使用用户电子邮件作为参数调用 Web 应用程序 2,因为如果他们共享来自 Web 应用程序 2 的链接,则任何人都可以看到这些数据,而我正在处理非常敏感的数据。
我意识到我可以将这些参数放在单独的工作表中,并给予它们仅查看访问权限,并且脚本将运行良好,但我是额外的,我想做得正确。
实际上,我还有一些其他功能需要以我的身份运行。如果你处于我的处境,你会从哪里开始?或者有人可以通俗地解释一下吗?我应该研究这样的事情吗?任何帮助表示赞赏!
小智 5
正如此处建议的,其中一种可能性是创建一个单独的 Web 应用程序来处理对 SpreadSheets 的访问。
客户端(主 Web 应用程序)将通过UrlFetchApp中间件(负责查询 SpreadSheet 的 Web 应用程序)发出请求,中间件将进行所需的查询并将其返回给客户端。最后,根据获得的响应,将呈现一种或另一种内容。
首先,我们创建两个 GAS 项目,一个称为 Main,另一个称为中间件。要点是中间件将作为 运行,USER_DEPLOYING客户端将作为 运行USER_ACCESSING。这允许访问工作表而不需要额外的权限。
该appscripts.json文件在客户端上看起来像这样。:
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/userinfo.email"
],
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "ANYONE"
}
Run Code Online (Sandbox Code Playgroud)
在中间件上就像这样:
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets"
],
"webapp": {
"executeAs": "USER_DEPLOYING",
"access": "ANYONE_ANONYMOUS"
}
Run Code Online (Sandbox Code Playgroud)
如果您对编辑或查看有任何疑问appscript.json,请查看清单和范围文档。
注意:"access": "ANYONE"和"access": "ANYONE_ANONYMOUS"仅用于测试目的。这是危险的,应该根据项目的特定需求进行审查。
对于客户端来说,我们只需要询问正在访问的用户的电子邮件Session.getActiveUser().getEmail(),然后将其发送给中间件即可获得响应。根据获得的响应,我们将呈现一种或另一种内容(我假设存在两个角色: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>" )
}
Run Code Online (Sandbox Code Playgroud)
对于中间件,我们需要获取该电子邮件并将其与我们的工作表进行比较,以检查用户的访问级别。然后我们返回结果。
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
}))
};
Run Code Online (Sandbox Code Playgroud)
最后,您访问主 Web 应用程序以检查一切是否正常。
请记住,这是一个测试实现,不应在生产中使用。如果您需要有关这些主题的更多信息,可以访问以下链接:
| 归档时间: |
|
| 查看次数: |
1894 次 |
| 最近记录: |