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

使用委托凭据调用Google Drive API时遭遇HttpError 401错误

问题描述

我用Python调用Google API查看组织内所有用户的文件,已配置带全域委派的服务账号,尝试为每个用户创建委托凭据以访问其文件。但循环内执行drive_service.files().list()时,抛出401无效凭据错误:

googleapiclient.errors.HttpError: <HttpError 401 when requesting https://www.googleapis.com/drive/v3/files?pageSize=10&fields=nextPageToken%2C+files%28id%2C+name%29&alt=json returned "Invalid Credentials". Details: "[{'domain': 'global', 'reason': 'authError', 'message': 'Invalid Credentials', 'locationType': 'header', 'location': 'Authorization'}]">

不使用委托凭据时代码可正常运行,已确认所需权限范围及Drive API已启用,怀疑问题出在del_creds上,且已反复确认全域委派已开启。

相关代码片段:

SCOPES = ['https://www.googleapis.com/auth/admin.directory.user', 'https://www.googleapis.com/auth/admin.directory.user.security', 'https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/drive.readonly']
CREDS = 'service-account-credentials.json'

def main():
    creds = service_account.Credentials.from_service_account_file(
        CREDS, scopes=SCOPES, subject='--my-email--')

    service = build('admin', 'directory_v1', credentials=creds)

    # 获取域内用户列表
    request = service.users().list(customer='--customer-code--', orderBy='email')
    response = request.execute()
    users = response.get('users', [])

    while request:
        request = service.users().list_next(previous_request=request, previous_response=response)
        if request:
            response = request.execute()
            users.extend(response.get('users', []))
    
    # 测试自身Drive访问(正常)
    drive_service = build('drive', 'v3', credentials=creds)
    results = drive_service.files().list(pageSize=10, fields="").execute()
    items = results.get('files', [])

    if not users:
        print('No users in the domain.')
    else:
        for user in users:
            email = user['primaryEmail']
            del_creds = creds.with_subject(email)

            drive_service = build('drive', 'v3', credentials=del_creds)

            # 报错位置
            results = drive_service.files().list(pageSize=10, fields="").execute()
            items = results.get('files', [])

            if not items:
                print('No files found.')
                return
            print('Files:')
            for item in items:
                print(u'{0} ({1})'.format(item['name'], item['id']))
排查与解决方案
  • 补全服务账号的全域委派权限授权
    即使开启了全域委派,若未在Google Admin控制台明确授权所需的SCOPES范围,依然会导致凭据无效。操作路径:Admin控制台 → 安全 → API控制 → 域范围委派 → 添加服务账号的客户端ID,输入所有需要的权限范围并保存。

  • 重新创建委托凭据而非复用初始凭据
    初始创建的creds已指定了subject='--my-email--',后续调用with_subject(email)会引发凭据状态冲突。应直接从服务账号文件重新生成凭据:

    # 替换循环内的del_creds创建逻辑
    del_creds = service_account.Credentials.from_service_account_file(
        CREDS, scopes=SCOPES, subject=email
    )
    
  • 验证目标用户状态
    确认循环中的用户邮箱是域内有效账号,且未被禁用;同时确保目标用户拥有Drive文件权限(虽不是401错误直接原因,但可避免后续逻辑误判)。

  • 修正fields参数
    代码中fields=""会导致API返回空字段,建议指定具体字段(如fields="nextPageToken,files(id,name)"),既符合API规范,也避免后续解析错误。

  • 添加凭据有效性检查
    委托凭据可能存在过期问题,可添加刷新逻辑确保凭据有效:

    if not del_creds.valid:
        del_creds.refresh(Request())
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:01:39