Python调用Google Workspace API获取用户时'my_customer'参数报错及含义疑问
问题背景
- 需求:列出Google Workspace内所有账号(仅一个组织,可在
https://admin.google.com的Directory->Users页面查看) - 运行代码时触发错误:
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://admin.googleapis.com/admin/directory/v1/users?customer=my_customer&maxResults=10&orderBy=email&alt=json returned "Invalid Input". Details: "[{'message': 'Invalid Input', 'domain': 'global', 'reason': 'invalid'}]">
代码示例
""" Google User Fetcher File: src/google_user_fetcher.py Updated: 30.09.2022 Fetches users from Google """ from __future__ import print_function import json from google.oauth2 import service_account from googleapiclient.discovery import build class GoogleUsersFetcher: # - Init --------------------------------------------------------------------------- def __init__(self): service = self.service_account_login() if service == "-1": print("GoogleUsersFetcher :: Could no login to API") else: # Call the API print("GoogleUsersFetcher :: Welcome to the API") self.list_users(service) # - Login to service account ------------------------------------------------------- def service_account_login(self): """ Reads service-key.json and logs into Google API :return: service (Service key of type googleapiclient.discovery.Resource) """ SCOPES = ['https://www.googleapis.com/auth/admin.directory.user.readonly'] service_account_info: dict = json.load(open('_tmp/service-key.json')) credentials = service_account.Credentials.from_service_account_info( service_account_info, scopes=SCOPES) service = build('admin', 'directory_v1', credentials=credentials) print(f"GoogleUsersFetcher :: Service OK {service}") return service # - List all users ----------------------------------------------------------------- def list_users(self, service): print("Getting the first 10 users in the domain") results = service.users().list(customer='my_customer', maxResults=10, orderBy='email').execute() users = results.get('users', []) if not users: print('No users in the domain.') else: print('Users:') for user in users: print(u'{0} ({1})'.format(user['primaryEmail'], user['name']['fullName'])) if __name__ == '__main__': GoogleUsersFetcher()
解答
1. my_customer的含义
my_customer是Google Workspace Directory API的专用占位符,指代当前授权账号所属的Google Workspace租户,和你理解的“外部客户”无关,这个参数本身是合法取值。
2. 错误的真实原因
你使用服务账号(service account)认证,但服务账号本身没有访问Workspace用户数据的权限,必须完成域范围授权(Domain-Wide Delegation),并在认证时模拟一个拥有Workspace管理员权限的账号(比如你的admin账号)。当前代码仅用服务账号自身凭证构建服务,未指定模拟的管理员账号,导致API请求权限不足,返回了模糊的"Invalid Input"错误。
3. 修复步骤
步骤1:完成域范围授权
在Google Workspace管理后台:
- 进入安全性 > API控制 > 域范围授权
- 添加服务账号的客户端ID(可在Google Cloud控制台的服务账号详情中找到)
- 授予权限范围:
https://www.googleapis.com/auth/admin.directory.user.readonly
步骤2:修改认证代码
创建凭证时添加subject参数,指定要模拟的管理员邮箱:
credentials = service_account.Credentials.from_service_account_info( service_account_info, scopes=SCOPES, subject='admin@your-domain.com' # 替换为你的Workspace管理员邮箱 )
步骤3:可选参数验证
若修复后仍有问题,可将customer='my_customer'替换为你的Workspace租户ID(在admin.google.com的账号 > 账号设置中获取),但通常my_customer可正常使用。
内容的提问来源于stack exchange,提问作者Europa

