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

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

问题描述

我有一个简单的应用程序脚本,该脚本在驱动器中搜索名为 something的文件夹,并列出其中的文件名(如果该文件夹不存在,则会创建该文件夹)。

  function doGet(){
var文件夹= DriveApp.getFoldersByName('something');
if(folders.hasNext()){
var files = folder.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'
}))
}
}

我将脚本部署为Web应用程序,以自己的身份执行该应用程序,然后进行测试



然后我将其重新发布为Web应用程序,并在访问Web应用程序的用户中执行。这次没有任何效果。我在浏览器中收到以下错误



' https://script.google.com/macros/s/AKfycbx4YQB_4WQ_JWJ_WJB_4WQW_JWJ_WJB@4WQW_JW9B href = http:// localhost:3000 rel = nofollow noreferrer> http:// localhost:3000 '已被CORS策略阻止:
对预检请求的响应未通过访问控制检查:请求的
资源上没有
'Access-Control-Allow-Origin'标头。如果不透明的响应满足您的需求,请将请求的
模式设置为 no-cors,以在禁用CORS的情况下获取资源。


由于没有身份验证,因此我预计会出现错误。我在react应用程序上设置了google OAuth2,添加了脚本和驱动器作用域,在google开发人员控制台中注册了该应用程序,并进行了所有设置,以便获得可以发送的 accessToken



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



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



我正在尝试使用创建一个Web应用google 登录按钮,当用户登录时调用我部署的 appscript 并在其驱动器中搜索文件夹名称 something,以便我可以显示我的Web应用程序中文件的名称。



这不是cors问题,如果我以自己的身份执行Web应用程序,则没有cors问题,并且零更改代码。我的问题是关于我如何授权应用程序脚本?我只提到cors错误,因为我正在展示到目前为止已经尝试过的东西。

解决方案

您将收到一个如果您的调用中有任何函数抛出异常,则会发生CORS错误,因为您没有 try ... catch 处理程序。当已部署的Web应用无法返回有效响应(即 HtmlOutput TextOutput ,Google的错误页面不包含任何CORS标头。



为防止这些掩盖的CORS错误,请用 try ... catch 包装您的Web应用程序入口点,以便可以报告实际错误。 / p>

即使不使用 try ... catch 包装Web应用程序的入口点,也很有可能通过查看项目的Stackdriver日志/ Stackdriver错误报告来访问基础错误。



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

  function doGet(e){
if(!e ||!validate_(e)){
return fail_();
}
试试{
return walkDriveContent(...);
}
catch(err){
console.error({message:驱动器行走失败: + err.message,堆栈:err.stack,错误:err});
return fail_();
}
}

函数fail_(){
return ContentService.createTextOutput( Sorry!);
}

函数validate_(eventObj){
/ **您的代码可确保这是一个有效的事件对象,您可以使用* /
//返回真正;
//或
//返回false;
}

函数walkDriveContent(folderName){
/ **
*您的代码可能会在此处引发异常,但否则
*返回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
   */
}

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

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