使用访问令牌调用Google Apps脚本Web应用程序

时间:2015-03-24 09:46:31

标签: oauth google-apps-script

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

编辑:我想我没有解释我想要完成的事情。以下是我尝试实现的工作流程:

  1. 我们授权用户使用OAuth2和Google访问我们的网站;
  2. 我们抓住了谷歌返回的她/他的访问令牌;
  3. 有一个Google Apps脚本网络应用程序,以运行Web应用程序的用户身份执行;
  4. 我们想通过提供访问令牌(2)来调用此应用(3),以便Google不再要求授权;
  5. 实际上,我们想要通过将用户重定向到该应用程序(3)来调用此应用程序(3),而不是将其称为Web服务。
  6. 由于

3 个答案:

答案 0 :(得分:1)

硬答案是否定的,您无法使用Apps脚本的内置服务和服务令牌。但是,如果您已经拥有由服务帐户生成的用户的令牌,则对用户数据的访问与任何其他语言非常相似。所有调用都将是您的令牌作用范围的服务的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 Script如此强大的便利性,主要是内置服务,但所有功能都可以通过Google REST API获得。

答案 1 :(得分:1)

马丁的答案最终对我有用,但是当我制作原型时,遇到了很大的障碍。

我需要手动添加以下范围,因为google apps脚本的“自动范围检测系统”没有要求它:"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)。我选择在清单文件中明确列出最低限度的作用域,但您也可以确保调用脚本将要求以不同方式访问驱动器的权限。我们有两个Google Apps脚本项目,即Caller和WebApp。

在Caller的清单文件中,即appsscript.json

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

在来电显示代码中

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 :(得分:0)

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

Authorization: Bearer <user's_access_token>