如何在Python Cloud Functions中继承认证或授权访问谷歌API?
问题描述
我本地开发了一个Python脚本,可通过Drive API从谷歌云端硬盘下载文件,再通过Sheets API上传文件。为给脚本授权,我下载了credentials.json,在IAM中完成账号授权并使用OAuth2,认证相关代码如下:
def main(): creds = None if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # If there are no (valid) credentials available, let the user log in. 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( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.json', 'w') as token: token.write(creds.to_json())
但我不清楚如何在Cloud Functions中实现该认证流程,Cloud Functions启动时是否已完成认证?我认为默认服务账户已配置为可访问所有API,但在认证实现上不知从何入手。
解决方案
核心逻辑:Cloud Functions的认证机制
Cloud Functions默认使用运行时服务账户(格式为[你的项目ID]@appspot.gserviceaccount.com),不需要本地那种交互式OAuth2登录流程(无服务器环境无法弹出登录页面)。默认服务账户并非自动拥有所有API权限,需要手动配置IAM权限。
具体步骤
1. 配置服务账户权限
- 进入Google Cloud控制台的IAM页面,找到默认服务账户(
[项目ID]@appspot.gserviceaccount.com)。 - 根据需求添加对应的IAM角色:
- 访问Drive API:可添加
Drive File Viewer(只读)或Drive File Editor(读写)。 - 访问Sheets API:可添加
Sheets Editor(读写)或更细粒度的角色。 - 遵循最小权限原则,不要直接赋予
Owner或Editor这类宽泛角色。
- 访问Drive API:可添加
2. 修改认证代码
移除本地的credentials.json和token.json相关逻辑,改用Application Default Credentials (ADC),它会自动从Cloud Functions运行环境中加载服务账户凭证:
from googleapiclient.discovery import build import google.auth # 定义需要的API权限范围(和本地脚本一致) SCOPES = ['https://www.googleapis.com/auth/drive.readonly', 'https://www.googleapis.com/auth/spreadsheets'] def get_credentials(): # ADC自动获取运行环境的服务账户凭证,并指定权限范围 creds, _ = google.auth.default(scopes=SCOPES) return creds # 初始化Drive和Sheets API客户端 drive_service = build('drive', 'v3', credentials=get_credentials()) sheets_service = build('sheets', 'v4', credentials=get_credentials())
如果不需要指定额外的权限范围,还可以更简化:
from googleapiclient.discovery import build # ADC会自动处理凭证 drive_service = build('drive', 'v3') sheets_service = build('sheets', 'v4')
3. 特殊场景处理
如果你的脚本需要访问用户个人的Drive/Sheets文件(而非服务账户自身的文件):
- 最简单的方式是让用户将目标文件共享给服务账户的邮箱(
[项目ID]@appspot.gserviceaccount.com),授予对应的读写权限。 - 若必须使用用户的OAuth2授权,需要实现服务端OAuth2流程,将用户的刷新令牌存储在Cloud Storage或Firebase等服务中,但这种方式复杂度较高,仅在必要时使用。
内容的提问来源于stack exchange,提问作者simplycoding
相关产品推荐
相关产品推荐

