使用委托凭据调用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

