如何在 Web 界面中授权应用程序脚本? [英] How do I authorize an app script in a web interface?

查看:32
本文介绍了如何在 Web 界面中授权应用程序脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的应用程序脚本,可以在驱动器中搜索名为某物"的文件夹,并列出其中的文件名(如果该文件夹不存在则创建它.

function doGet() {var folders = DriveApp.getFoldersByName('something');如果(文件夹.hasNext()){var files = folders.next().getFiles();var 文件名 = [];而 (files.hasNext()) {var file = files.next();fileNames.push(file.getName())};返回 ContentService.createTextOutput(JSON.stringify({'状态':'成功',输出":文件名}))} 别的 {DriveApp.createFolder('东西');返回 ContentService.createTextOutput(JSON.stringify({'状态':'成功','输出':'文件夹已创建'}))}}

我将脚本部署为 Web 应用程序,以我自己的身份执行该应用程序,使用来自浏览器中的 React 应用程序的 fetch 调用对其进行测试,一切都按预期工作.

然后我重新发布为网络应用程序,以访问网络应用程序的用户身份执行.这一次没有任何作用.我在浏览器中收到以下错误

<块引用>

访问获取'https://script.google.com/macros/s/x4DziUyc/macros/s/4DziW9WVwBsT_qruQHa_BrK508T4oD9ILY/exec一个>'来自 origin 'http://localhost:3000' 已被 CORS 政策阻止:对预检请求的响应未通过访问控制检查:否请求中存在Access-Control-Allow-Origin"标头资源.如果不透明的响应满足您的需求,请设置请求的模式为 'no-cors' 以在禁用 CORS 的情况下获取资源.

我预计会出现错误,因为没有身份验证.我在 React 应用程序上设置了 google OAuth2,添加了脚本和驱动范围,在 google 开发者控制台中注册了该应用程序并设置了所有内容,以便我获得一个 accessToken,我可以将它发送到带有 fetch 的标头中调用 google 脚本.

但我仍然收到与上述相同的错误.

我应该如何授权应用脚本应用以便任何人都可以运行它?

我正在尝试创建一个带有 google 登录按钮的网络应用程序,当用户登录时,它会调用我部署的 appscript 并在他们的驱动器中搜索文件夹命名某物",以便我可以在我的网络应用程序中显示文件的名称.

这不是 cors 问题,如果我自己执行 Web 应用程序,则没有 cors 问题并且代码更改为零.我的问题是关于我如何授权应用程序脚本?我只提到了 cors 错误,因为我展示了到目前为止我所尝试的.

解决方案

如果调用中的任何函数抛出异常,您将收到 CORS 错误,因为您没有 try...catch 处理程序.当部署的网络应用程序 未能返回有效响应(即 HtmlOutputTextOutput),Google 的错误页面不包含任何 CORS 标头.

为了防止这些屏蔽"CORS 错误,请使用 try...catch 包装您的网络应用入口点,以便报告实际错误.

即使没有使用 try...catch 包装您的 web 应用程序的入口点,您也很可能能够通过查看项目的 Stackdriver 日志/Stackdriver 错误报告来访问底层错误.

这是一个简单的例子,演示了一些事件对象验证,以确保请求来自你关心的地方 &格式良好,然后调用一个函数,该函数可能会为无效/未经授权的操作抛出异常.在任何一种情况下,它都会返回一个不透明的面向用户的响应(抱歉!"),并且对于错误将生成 Stackdriver 日志.它无法捕获因违反执行时间配额而发生的异常,因为您的脚本只是被终止了.

function doGet(e) {如果 (!e || !validate_(e)) {返回失败_();}尝试 {返回 walkDriveContent(...);}抓住(错误){console.error({message: "Drive walk failed:" + err.message, stack: err.stack, error: err});返回失败_();}}函数失败_(){return ContentService.createTextOutput("对不起!");}功能验证_(eventObj){/** 此处的代码可确保这是您可以使用的有效事件对象 *///返回真;//    或者//返回假;}功能walkDriveContent(文件夹名称){/*** 您的代码可能会在此处抛出异常,但否则* 返回 TextOutput 或 HtmlOutput*/}

I have a simple app script that searches drive for a folder named 'something' and lists the names of files inside if the folder doesn't exist it creates it.

function doGet() {
 var folders = DriveApp.getFoldersByName('something');
 if (folders.hasNext()) {
  var files = folders.next().getFiles();
    var fileNames  = [];
    while (files.hasNext()) {
      var file = files.next();
      fileNames.push(file.getName())
    };
    return ContentService.createTextOutput(JSON.stringify({
        'status': 'success',
        'output': fileNames
    }))

  } else {
    DriveApp.createFolder('something');
    return ContentService.createTextOutput(JSON.stringify({
        'status': 'success',
        'output': 'folder created'
    }))
  }
}

I deploy the script as a web app, execute the app as myself, test it out using a fetch call from a react app in a browser and everything work as expected.

Then I republish as a web app, executing as the user accessing the web app. This time nothing works. I get the following error in the browser

Access to fetch at 'https://script.google.com/macros/s/AKfycbx4eQ60DziUy4hSjnJidW9WVwBsT_qruQHa_BrK508T4oD9ILY/exec' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

I expected an error since there is no authentication. I set up google OAuth2 on the react app, added scripts and drive scopes, register the app in google developer console and set everything up so that I get an accessToken that I can send in the header with the fetch call to the google script.

But I still get the same error as above.

How am I supposed to authorize an app script app so that anyone can run it?

I am trying to create a web app with a google sign in button, when the user signins in it calls the appscript I deployed and searches their drive for a folder names 'something' so that I can display the names of files in my web app.

This is not a cors issue, if I execute the web app as myself there is no cors problems and zero changes to the code. My question is regarding how I authorise an app script? I only mention the cors error because I was showing what I have tried so far.

解决方案

You will receive a CORS error if any function in your call throws an exception, since you have no try...catch handler. When a deployed webapp fails to return a valid response (i.e. either an HtmlOutput or TextOutput), Google's error page does not include any CORS headers.

To prevent these "masking" CORS errors, wrap your web app entry points with try...catch so that the actual error can be reported.

Even without wrapping your webapp's entry points with try...catch, it is very likely that you are able to access the underlying error by viewing your project's Stackdriver logs / Stackdriver Error Reporting.

This is a simple example, demonstrating some event object validation to ensure that the request is from somewhere you care about & is well-formed, and then calls a function that may throw an exception for invalid / unauthorized operations. In either case, it returns an opaque user-facing response ("Sorry!") and for errors will generate a Stackdriver log. It cannot catch the exception that occurs for an execution time quota breach, since your script is simply killed.

function doGet(e) {
  if (!e || !validate_(e)) {
    return fail_();
  }
  try {
    return walkDriveContent(...);
  }
  catch (err) {
    console.error({message: "Drive walk failed: " + err.message, stack: err.stack, error: err});
    return fail_();
  }
}

function fail_() {
  return ContentService.createTextOutput("Sorry!");
}

function validate_(eventObj) {
 /** your code here that ensures this is a valid event object you can work with */
 // return true;
 //     or
 // return false;
}

function walkDriveContent(folderName) {
  /**
   * Your code that may throw exceptions here, but otherwise
   * returns TextOutput or HtmlOutput
   */
}

这篇关于如何在 Web 界面中授权应用程序脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆