OAuth Google People API刷新令牌在联系人权限下失效问题排查
问题描述
通过OAuth获取了包含以下权限的访问令牌和刷新令牌:
const scopes = [ "https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/contacts.readonly", "https://www.googleapis.com/auth/contacts.other.readonly", ];
此前仅使用calendar权限时,访问令牌过期前后一切正常。集成联系人及其他联系人权限后,能正常获取令牌并调用Calendar和People API,但访问令牌过期刷新后,调用People API的searchContacts接口时出现如下403错误:
<HttpError 403 when requesting https://people.googleapis.com/v1/people:searchContacts?pageSize=5&query=sofia&readMask=names%2CemailAddresses&alt=json returned "Request had insufficient authentication scopes.". Details: "[{'@type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', 'domain': 'googleapis.com', 'metadata': {'method': 'google.people.v1.PeopleService.SearchContacts', 'service': 'people.googleapis.com'}}]">
Python逻辑已执行令牌刷新,控制台打印了刷新后的日志且数据库已更新令牌,但仍出现该错误,请问问题出在哪里?
可能的原因及解决方案
1. 旧刷新令牌未包含新增的权限范围
如果首次授权时仅请求了calendar权限,后续新增联系人权限后,旧的刷新令牌不会自动继承新权限。哪怕当前代码指定了完整scopes,只要用户未重新授权,刷新令牌生成的访问令牌仍只有原授权范围。
解决:
- 强制用户重新走OAuth授权流程,确保授权请求包含所有需要的scopes。
- 授权时添加
prompt=consent参数,强制用户重新确认权限,避免浏览器缓存旧授权信息。
2. 刷新令牌时未正确处理权限范围
检查Python刷新令牌的逻辑:
- 是否在刷新请求中明确指定了完整scopes?部分OAuth库刷新时若不指定,会默认使用原授权范围。
- 验证新访问令牌的实际权限:调用
https://oauth2.googleapis.com/tokeninfo?access_token=YOUR_NEW_TOKEN,查看返回的scope字段,确认是否包含contacts.readonly和contacts.other.readonly。
3. 代码误用了旧访问令牌
虽然日志和数据库显示令牌已更新,但可能存在:
- 代码中有令牌缓存,刷新后未及时清除,调用API时仍用旧令牌。
- 多线程/进程环境下,部分进程未读取到数据库更新后的新令牌,仍使用内存中的旧值。
解决:
- 检查缓存逻辑,确保刷新后立即清除相关缓存。
- 调用API前,确认使用的是刚从数据库读取的最新令牌,而非内存缓存的旧值。
4. 验证接口权限匹配性
searchContacts接口确实需要https://www.googleapis.com/auth/contacts.readonly权限,你的scopes已包含,但如果刷新后的令牌未携带该权限,就会触发报错。重点通过第2点的令牌信息接口验证实际权限范围。
内容的提问来源于stack exchange,提问作者Diego H. O'Hagan
相关产品推荐
相关产品推荐

