You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Cloud Function调用Apps Script API时出现403权限错误

Workspace插件后台任务流程中无权限用户触发403错误的解决

问题背景

我正在开发一款可从Google Drive启动、以后台任务形式运行的Workspace插件。实现逻辑为:Apps Script插件调用Google Cloud Function(GCF),再由GCF通过Apps Script API回调Apps Script(因流程耗时较长)。

已声明的OAuth权限范围

"oauthScopes": [
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/drive.addons.metadata.readonly",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/script.scriptapp"
  ],

流程步骤

  • 用户打开插件,授予上述权限范围的访问权限;
  • 用户选择要处理的Google Drive文件并点击按钮;
  • Apps Script调用GCF,同时发送用户的OAuth令牌;
  • GCF以该OAuth令牌为身份验证载体,通过Apps Script API调用我的Apps Script函数;
  • 核心问题:无GCP项目及Apps Script项目权限的用户尝试使用插件时,触发403错误。

环境与配置信息

  • Apps Script与GCF位于同一GCP项目,已启用Apps Script API;
  • Apps Script项目已部署为Workspace插件(正在接受Marketplace团队审核),仅我拥有访问权限;
  • 使用服务账户身份令牌从Apps Script调用GCF;
  • 尝试使用已授权用户的OAuth令牌从GCF回调Apps Script;
  • 清单中设置了"executionAPI access: anyone",但不确定是否生效;
  • 测试验证:Apps Script项目编辑者账户可正常运行流程,仅读者权限或无权限的账户失败,说明GCF回调时使用的Bearer令牌不足以授权账户。

相关代码

Apps Script调用GCF的代码

const userToken = ScriptApp.getOAuthToken();
const resp = UrlFetchApp.fetch(BACKGROUND_GCF_URL + '?userToken=' + userToken + '&fileId=' + fileId + '&execUid=' + execUid, {
    headers: {
      Authorization: 'Bearer ' + bearer // 服务账户生成的身份令牌
    },
    muteHttpExceptions: true
})

GCF调用Apps Script API的代码

const body = {
    function: 'receiveGCFcall',
    parameters: [
        execUid, fileId, userToken
    ],
    devMode: true
 }

 const config = {
     headers: {
         Authorization: 'Bearer ' + userToken
     }
 }
 
 axios
  .post(URL, body, config)
  .then(resp => {
    console.log(`statusCode: ${resp.status}`);
    console.log(`data: ${JSON.stringify(resp.data)}`)
    if(resp.data.result === 'NOT OK') {
      console.error(`[${execUid}] Something went wrong, the slides have not been updated`)
    }
  }).catch(...) // 此处触发403错误

问题根源

当前使用用户OAuth令牌调用Apps Script API时,令牌仅能代表用户自身权限。对于无Apps Script项目权限的用户,即使已授予插件OAuth权限,也无法通过API执行该脚本——因为script.scriptapp权限仅允许用户操作自己创建或拥有权限的脚本,而非第三方插件的后台脚本。

解决方法

1. 使用服务账户进行API调用(推荐)

由于GCF和Apps Script同属一个GCP项目,可使用GCP服务账户(而非用户令牌)调用Apps Script API,确保调用身份拥有脚本执行权限:

  • 给服务账户授予Apps Script项目的编辑者权限;
  • 在GCF中使用服务账户生成的OAuth令牌(而非用户令牌)发起API调用;
  • 若需操作用户的Drive文件,可通过**域范围授权(Domain-Wide Delegation)**让服务账户模拟用户身份执行操作(仅适用于Workspace域用户)。

2. 调整脚本执行权限配置

确保Apps Script项目的执行API权限正确设置:

  • 在Apps Script编辑器中,进入项目设置 > 执行API访问权限,选择“任何人”或“任何人,甚至匿名”(根据需求选择);
  • 确认清单文件中的executionApi.access字段设置为"ANYONE":
"executionApi": {
  "access": "ANYONE"
}

3. 移除devMode参数

当前代码中devMode: true仅允许脚本开发者执行API调用,需移除该参数,使用生产部署版本:

const body = {
    function: 'receiveGCFcall',
    parameters: [execUid, fileId, userToken]
    // 移除devMode字段
 }

4. 补充用户令牌权限范围

确保用户令牌包含https://www.googleapis.com/auth/script.run权限(当前清单未声明),该权限允许用户通过API执行插件关联的脚本。更新OAuth权限范围:

"oauthScopes": [
    // 原有权限...
    "https://www.googleapis.com/auth/script.run"
  ],

注意事项

  • 若插件面向外部非Workspace域用户,域范围授权不可用,需确保脚本执行权限设置为“任何人”,并使用服务账户调用API;
  • 提交Marketplace审核时,需明确说明各权限的使用目的,避免因权限范围过大被拒。

内容的提问来源于stack exchange,提问作者ValLeNain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:20:23