Google OAuth用户数据获取异常及People API权限问题排查
谷歌OAuth获取用户数据问题排查与解决
初始问题
通过获取到的access token调用https://openidconnect.googleapis.com/v1/userinfo接口,仅返回以下精简数据:
{ "sub": "123", "picture": "https:lh3.googleusercontent.com/..." }
同时调用People API接口https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses时,返回权限不足错误:
{ "error": { "code": 403, "message": "Request had insufficient authentication scopes.", "status": "PERMISSION_DENIED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT", "domain": "googleapis.com", "metadata": { "service": "people.googleapis.com", "method": "google.people.v1.PeopleService.GetPerson" } } ] } }
相关代码配置:
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID") GOOGLE_SECRET = os.getenv("GOOGLE_SECRET") GOOGLE_URL = "https://accounts.google.com/o/oauth2/v2/auth?" GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token?" GOOGLE_SCOPE = "openid profile email" GOOGLE_REDIRECT_URI = "http://localhost:8050/google-callback"
回调及token获取逻辑:
@server.route("/google-callback") def google_callback_route(): access_token = get_access_token(request.full_path, GOOGLE_TOKEN_URL, GOOGLE_CLIENT_ID, GOOGLE_REDIRECT_URI, GOOGLE_SECRET ) # todo: make call to userinfo endpoint return None
def get_access_token(url: str, token_url: str, client_id: str, redirect_uri, client_secret=None) -> str: """Calls the oauth server and gets the access token based on the code""" query_params = urlparse(url).query code = parse_qs(query_params)['code'][0] body = { "client_id": client_id, "grant_type": AUTHORIZATION_CODE, "code": code, "redirect_uri": redirect_uri } if client_secret is not None: body['client_secret'] = client_secret response = requests.post(url=token_url, data=body) access_token = response.json()['access_token'] return access_token
调整后问题
修改scope为:
GOOGLE_SCOPE = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email"
并在谷歌控制台启用People API后,调用People API能获取姓名数据,但仍无法拿到邮箱信息:
{ "resourceName": "people/123", "etag": "some-etag", "names": [ { "metadata": { "primary": true, "source": { "type": "PROFILE", "id": "123" }, "sourcePrimary": true }, "displayName": "John Doe", "familyName": "Doe", "givenName": "John", "displayNameLastFirst": "Doe, John", "unstructuredName": "John Doe" } ] }
最终解决方案
问题根源是登录页面被浏览器缓存,导致授权请求仍使用旧的scope配置。按下Ctrl+R强制刷新登录页面后,即可正常获取包含邮箱在内的完整用户数据。
内容的提问来源于stack exchange,提问作者0xJanAbe
相关产品推荐
相关产品推荐

