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

如何使用Google服务账号实现Google Apps Script Web App端点授权并模拟自身身份访问

解决Google Apps Script Web App「仅我」权限下的服务账号访问问题

你的核心问题在于:服务账号无法直接模拟你的个人Google账号访问设置为「仅我」权限的Web App。原因很简单:这类Web App的访问权限严格绑定到你的个人账号身份,服务账号是独立的Google身份实体,既不在「仅我」的权限范围内,也无法被直接授权访问这类仅限个人的资源(Google没有提供给服务账号授予「仅我」Web App权限的途径)。

下面给你两种可行的解决方案,对应不同的需求场景:

方案一:用个人账号OAuth 2.0授权访问(推荐,符合「仅我」权限要求)

既然Web App仅限你个人访问,最直接的方式是通过OAuth 2.0授权码流程,获取你个人账号的访问令牌(AccessToken),再用这个令牌发起请求。

操作步骤:

  1. 打开和你的GAS项目绑定的Google Cloud Console项目,创建OAuth客户端ID:
    • 选择「桌面应用」类型,下载客户端配置文件(credentials.json)。
  2. 使用google-auth-oauthlib库实现授权流程:
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import requests
import os
import pickle

# 定义OAuth范围:GAS Web App需要的范围是https://www.googleapis.com/auth/script.external_request
SCOPES = ['https://www.googleapis.com/auth/script.external_request']
WEB_APP_URL = 'https://script.google.com/a/macros/<my_project>/s/<my_script_id>/exec'
CREDS_PATH = '/path/to/credentials.json'
TOKEN_PATH = 'token.pickle'

def get_credentials():
    creds = None
    # 加载已保存的令牌
    if os.path.exists(TOKEN_PATH):
        with open(TOKEN_PATH, 'rb') as token:
            creds = pickle.load(token)
    # 无有效令牌时,发起授权流程
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(CREDS_PATH, SCOPES)
            creds = flow.run_local_server(port=0)
        # 保存令牌供下次使用
        with open(TOKEN_PATH, 'wb') as token:
            pickle.dump(creds, token)
    return creds

# 获取凭证并发起请求
creds = get_credentials()
authed_session = requests.Session()
authed_session.headers.update({'Authorization': f'Bearer {creds.token}'})

resp = authed_session.get(WEB_APP_URL)
print(resp.status_code)
print(resp.text)

第一次运行时,会弹出浏览器让你登录个人Google账号授权,之后令牌会被保存,后续无需重复授权。

方案二:调整Web App权限+服务账号授权(不推荐,放宽了权限)

如果你坚持要用服务账号访问,只能先放宽Web App的访问权限:

  1. 修改GAS Web App的「访问权限」为「任何人,甚至匿名」或者「组织内的任何人」(如果你用的是Workspace账号)。
  2. 在Web App的代码中添加权限校验:比如检查请求中的服务账号邮箱,只允许特定服务账号访问。

示例修改后的GAS代码:

function doGet(e) {
  // 获取请求中的身份信息
  const userSession = Session.getActiveUser();
  const allowedServiceAccount = 'your-service-account@<project-id>.iam.gserviceaccount.com';
  
  // 校验是否是指定服务账号
  if (userSession.getEmail() === allowedServiceAccount) {
    boolResult = isDailyGmailCountLargerThan10()
    console.log(boolResult)
    if(boolResult) return ContentService.createTextOutput('Done');
    else return ContentService.createTextOutput('Error');
  } else {
    return ContentService.createTextOutput('Unauthorized').setStatusCode(401);
  }
}

function isDailyGmailCountLargerThan10(){
  intCount = GmailApp.search("newer_than:1d").length;
  return intCount > 10;
}

之后你原来的服务账号请求代码就能正常工作了,但注意这种方式已经不再是「仅我」权限,而是允许指定服务账号访问。

关键误区说明

你尝试用服务账号的ID Token去访问是行不通的,因为:

  • ID Token只是证明服务账号的身份,而Web App的「仅我」权限只认可你的个人账号身份。
  • 域范围委派(Domain-Wide Delegation)仅适用于Google Workspace域管理员,个人Google账号无法使用该功能来让服务账号模拟个人身份。

内容的提问来源于stack exchange,提问作者Question-er XDD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:37:41