【问题标题】:Google Apps Script WebApp with Simultaneous Users Overrides User Recognition具有同时用户的 Google Apps 脚本 WebApp 会覆盖用户识别
【发布时间】:2021-12-30 10:07:25
【问题描述】:

我有一个项目允许用户发送只包含一些细节的表单。我曾经使用谷歌的 Session 类,但是当多个帐户登录或其他一些我无法修复数周的原因时,一切都会变得混乱。所以我决定尝试另一种方法并完全取消谷歌身份验证,并从我的 LMS 的 POST 数据中获取用户验证并将其设置为 UserProperty。在没有 Google Auth 的情况下一切正常,我今天进行了大规模测试。结果,由于我的脚本必须以“我”身份运行,因此所述用户是脚本所有者帐户,这反过来又使所有用户的 UserProperty 成为一种 ScriptProperty,并且他们开始覆盖彼此的用户详细信息。

例如,第二个用户从他们的 LMS 打开 WebApp 会覆盖第一个用户的用户详细信息,因为第一个用户的详细信息被第二个用户覆盖,所有提交似乎都是由第二个用户发送的。代码如下;

  function doPost(e) {
  var postContents = e.postData.contents.split("&");
  var postSplit = postContents[16].split("=");
  var activeUserEmail = postSplit[1].replace("%40", "@");
  userProperties.setProperty('activeUserEmail', activeUserEmail);

  if (activeUserEmail[2] == "s" || activeUserEmail[2] == ".") {
    console.log("Redirecting to Student: " + activeUserEmail);
    return HtmlService.createTemplateFromFile('student_form')
      .evaluate()
      .addMetaTag('viewport', 'width=device-width, initial-scale=1')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  } 

用户在 html 页面上通过 google.script.run 使用 successhandler 调用此函数,并在对电子表格和云端硬盘进行更多处理后传回页面。

function getData() {
  var activeUserEmail = userProperties.getProperty('activeUserEmail');
  console.log("getData User: " + activeUserEmail);
  try {
    if (activeUserEmail != "") {
      var userResults = teachersSheet.filter(function (row) { return row[0] == activeUserEmail; });
    } else {
      var userResults = "No User Email"
    }
    var userDepartment = userResults[0][2];

    if (userDepartment == "Admin") {
      var data = questionsSheet.getDisplayValues().filter(function (row) { return row[1] != "" && row[0] != "ID"; });
    }
    else {
      var data = questionsSheet.getDisplayValues().filter(function (row) { return row[3] == userDepartment && row[9] == "FALSE" && row[1] != ""; });
    };

    var data = [userResults, data];
    console.log(data);
    return data;
  } catch (e) {
    console.log(e);
  }
}

代码可能有点乱,但希望这样就足够了。

我不知道如何将持久的用户详细信息保存在不会被第二个脚本运行器覆盖的变量或属性中。有什么想法吗?

【问题讨论】:

    标签: javascript authentication google-apps-script


    【解决方案1】:

    可以通过在其中存储unique id 来维护状态

    • 用户属性和
    • 客户端 Javascript 变量
    const id = Utilities.getUuid()
    userProperties.setProperty(String(id), activeUserEmail);
    

    student_form html 还需要是 evaluated 和 idid,一次在客户端应该与每个请求一起发送到服务器。

    google.script.run.getData(id)
    
    function getData(id) {
      var activeUserEmail = userProperties.getProperty(String(id));
      console.log("getData User: " + activeUserEmail);
      //stuff
    

    【讨论】:

    • 我已经按照你的建议做了,但是像你之前用const id = <? id ?> 回答的那样引用评估的 id 变量会在控制台上抛出一个Uncaught SyntaxError with "Unexpected token '<',然后是 id is not defined 错误。我在 JS 文件的应用程序脚本调用之前添加了 const。
    • @Anıl 试试const id = "<?= id ?>"。如果这不起作用,请使用您的 html 提出一个新问题
    • 我认为它必须对包含的 JS 文件做一些事情,我将引用移动到 index html 文件并做了 ?= 现在它可以工作了。我只会知道这是否真的在周一的大规模测试中有效,但它应该在理论上有效。我目前遇到的问题是我正在传递一个表单,显然 GAS 不允许传递表单对象以外的任何东西。 Forms with file inputs must be the only parameter. 还不确定我会如何解决它
    • 更新:我在表单中添加了一个隐藏的 id 元素并在那里传递了 id 值并从 GAS 中读取它,不知道为什么我一开始没有想到它.谢谢大师的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    相关资源
    最近更新 更多