【问题标题】:Calling a Google Apps Script web app with access token使用访问令牌调用 Google Apps Script Web 应用程序
【发布时间】:2021-07-20 09:58:54
【问题描述】:

我需要代表登录到我的系统的用户执行 GAS 服务。所以我有她/他的访问令牌。我想以某种方式将令牌转移到网络应用程序,而无需再次授权用户将其用于某些活动。这可以实现吗?谢谢。

编辑:我想我没有正确解释我试图完成的事情。这是我尝试实现的工作流程:

  1. 我们授权使用 OAuth2 和 Google 访问我们网站的用户;
  2. 我们获取了 Google 返回的她/他的访问令牌;
  3. 有一个 Google Apps Script Web 应用程序作为运行 Web 应用程序的用户执行;
  4. 我们希望通过提供访问令牌 (2) 来调用此应用 (3),以便 Google 不再要求授权;
  5. 实际上,我们希望调用此应用 (3),而不是将用户重定向到它,而是将其作为 Web 服务调用。

谢谢

【问题讨论】:

  • 我真的很怀疑,但会极大地帮助我。
  • 这可以通过几种方式来完成。脚本是如何从 IDE、触发器、驱动应用等运行的?
  • @SpencerEaston 它是从我的后端调用的。
  • 您是否通过服务帐户从后端获取令牌?
  • @SpencerEaston 是的,我们使用 OAuth2。

标签: google-apps-script web-applications oauth


【解决方案1】:

Martin 的回答最终对我有用,但在我制作原型时遇到了一个重大障碍。

我需要手动添加以下范围,因为谷歌应用脚​​本的“自动范围检测系统”没有要求:"https://www.googleapis.com/auth/drive.readonly"。这导致UrlFetchApp.fetch 总是给 401 提供我不理解的附加信息。记录此附加信息将显示 html,包括以下字符串

Sorry, unable to open the file at this time.</p><p> Please check the address and try again.

我仍然不明白为什么需要"https://www.googleapis.com/auth/drive.readonly"。这可能与我们可以使用/dev url有关,但是使用脚本文件的驱动器权限来检查谁可以使用/dev url。

也就是说,以下设置适用于我(它也适用于 doGet 等,但我选择了 doPost)。我选择在清单文件中明确列出最少需要的范围,但您也可以确保调用脚本会要求以不同方式访问驱动器的权限。我们有两个谷歌应用脚​​本项目,Caller 和 WebApp。

在Caller的manifest文件中,即appsscript.json

{
  ...
  "oauthScopes": 
  [
    "https://www.googleapis.com/auth/drive.readonly",
    "https://www.googleapis.com/auth/script.external_request"]
}

在调用者的 Code.gs 中

function controlCallSimpleService(){

  var webAppUrl ='https://script.google.com/a/DOMAIN/macros/s/id123123123/exec';

//  var webAppUrl = 
//  'https://script.google.com/a/DOMAIN/macros/s/id1212121212/dev'

  var token = ScriptApp.getOAuthToken();

  var options = {
    'method' : 'post'
    , 'headers': {'Authorization': 'Bearer '+  token}
    , muteHttpExceptions: true
  };

  var response = UrlFetchApp.fetch(webAppUrl, options);
  Logger.log(response.getContentText());
}

在 WebApp 的 Code.gs 中(被调用的 Web 应用)

function doPost(event){
  return ContentService.createTextOutput("Hello World");
}

【讨论】:

    【解决方案2】:

    硬性答案是否定的,您不能将 Apps Script 的内置服务与服务令牌一起使用。但是,如果您已经拥有由服务帐户生成的用户令牌,那么对用户数据的访问与任何其他语言都非常相似。所有调用都将针对您的令牌所针对的服务的 REST 接口。

    以这个小脚本为例。它将构建所有用户文件夹的列表并将它们作为 JSON 返回:

     function doGet(e){
      var token = e.parameter.token;
      var folderArray = [];
      var pageToken = "";
      var query = encodeURIComponent("mimeType = 'application/vnd.google-apps.folder'");
      var params = {method:"GET",
                    contentType:'application/json',
                    headers:{Authorization:"Bearer "+token},
                    muteHttpExceptions:true
                   };
    
      var url = "https://www.googleapis.com/drive/v2/files?q="+query;
    
      do{
        var results = UrlFetchApp.fetch(url,params); 
        if(results.getResponseCode() != 200){
          Logger.log(results);
          break;
        }
    
        var folders = JSON.parse(results.getContentText());
        url = "https://www.googleapis.com/drive/v2/files?q="+query;  
    
        for(var i in folders.items){
          folderArray.push({"name":folders.items[i].title, "id":folders.items[i].id})
        }
    
        pageToken = folders.nextPageToken;
        url += "&pageToken="+encodeURIComponent(pageToken);
      }while(pageToken != undefined)
    
      var folderObj = {};
      folderObj["folders"] = folderArray;      
      return ContentService.createTextOutput(JSON.stringify(folderObj)).setMimeType(ContentService.MimeType.JSON);
    }
    

    您确实错过了使 Apps 脚本如此强大的许多便利,主要是内置服务,但所有功能都可以通过 Google REST API 获得。

    【讨论】:

    • 感谢您的回复,但这不是我们需要的。请检查编辑,我想,更好的解释。
    【解决方案3】:

    我找到了方法!只需在请求中包含以下标头:

    Authorization: Bearer <user's_access_token>

    【讨论】:

    • 嘿。我也想对我的 chrome 扩展和应用脚本做同样的事情。但是使用这种方法对我不起作用。我确保应用程序脚本和扩展程序都是谷歌开发者控制台中同一个项目的一部分。还有什么需要我照顾的吗?
    • 谢谢,这行得通 - 但是,我意识到访问令牌会在一小时后过期,这对于使其成为长期解决方案不起作用。是否有任何不涉及另一个中间步骤的解决方法,我们将用户的刷新令牌交换为访问令牌?
    猜你喜欢
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 2015-10-09
    • 2019-10-15
    • 2021-11-07
    • 1970-01-01
    相关资源
    最近更新 更多