Google People API无法获取域内其他用户头像问题排查
故障原因
你遇到的问题由3个明确问题导致,和前端头像可见性设置无关:
- 核心权限问题:你在服务账号凭证中固定将
subject设置为个人普通员工邮箱,整个接口调用全程使用普通员工权限执行。listDirectoryPeople接口的普通用户权限存在设计限制:仅会返回调用者本人的自定义头像数据,其余域内用户的photos字段会被默认过滤返回空值,即使用户已经把头像设置为全域可见也不会返回。 - Scope配置缺失:你当前配置的
https://www.googleapis.com/auth/directory.readonly是旧版Drive共享目录的读取权限,不是Google Workspace全域用户目录的读取权限,缺少管理员级别的目录读取授权,无法拉取全量用户的完整档案字段。 - 调试代码逻辑错误:你的打印语句写在了
for循环外部,仅会输出循环遍历到的最后一个用户的字段值,前面所有用户的字段数据根本没有被打印,进一步干扰了调试判断。
修复方案
第一步:补全后台权限配置
- 进入Google Workspace管理后台的域范围委派配置页,给你正在使用的服务账号追加以下授权scope:
https://www.googleapis.com/auth/userinfo.profilehttps://www.googleapis.com/auth/contacts.readonlyhttps://www.googleapis.com/auth/admin.directory.user.readonly
- 将代码中凭证初始化的
subject字段值替换为你公司Google Workspace的超级管理员账号邮箱,禁止使用普通员工账号作为委派主体。 - 检查Workspace后台的目录共享设置,确认「用户个人资料-照片」字段设置为对全域可见,不要设置为仅管理员可见。
第二步:修正代码逻辑
替换原有测试代码为以下逻辑,修复循环打印bug,同时正确分页拉取全量数据:
from google.oauth2 import service_account from googleapiclient.discovery import build SERVICE_ACCOUNT_FILE = 'creds.json' # 替换为你的域超级管理员邮箱 ADMIN_ACCOUNT = 'admin@your-company-domain.com' SCOPES = [ 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/contacts.readonly', 'https://www.googleapis.com/auth/admin.directory.user.readonly' ] credentials = service_account.Credentials.from_service_account_file( filename=SERVICE_ACCOUNT_FILE, scopes=SCOPES, subject=ADMIN_ACCOUNT ) people_service = build('people', 'v1', credentials=credentials) all_directory_users = [] next_page_token = None # 循环拉取全部分页数据 while True: request_params = { 'readMask': 'names,photos,emailAddresses', 'sources': 'DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE', 'pageSize': 1000 } if next_page_token: request_params['pageToken'] = next_page_token resp = people_service.people().listDirectoryPeople(**request_params).execute() all_directory_users.extend(resp.get('people', [])) next_page_token = resp.get('nextPageToken') if not next_page_token: break # 遍历打印所有用户的头像信息 for user in all_directory_users: name_data = user.get('names', []) photo_data = user.get('photos', []) user_name = name_data[0].get('displayName') if name_data else '未获取到姓名' avatar_url = photo_data[0].get('url') if photo_data else '未获取到头像' print(f"用户:{user_name},头像地址:{avatar_url}")
注意:如果后续需要把头像嵌入邮件签名,不要直接引用返回的Google头像URL,这个URL有临时访问鉴权,会过期失效,需要把头像二进制数据下载后转成base64嵌入签名,或者上传到你公司自己的静态资源服务器存成固定地址。
内容的提问来源于stack exchange,提问作者Dragonborn_OW
相关产品推荐
相关产品推荐

