问题:缺少 OAuth 2 刷新令牌。
问题是本地主机版本收到
Refresh Token
作为授予令牌的一部分,但在 GCE 中运行的相同代码却没有。
详情:
我编写了一个实现 Google OAuth 2.0 的 Python Flask 应用程序。此 Web 应用程序在云中运行,具有经过验证的域名、有效的 SSL 证书和 HTTPS 端点。此 Web 应用程序未经修改也以
localhost
的形式运行。运行时之间的差异在于 localhost 版本不使用 TLS。代码流程没有其他差异。
除了
Refresh Token
丢失并且我无法自动续订token
之外,一切都很完美。
我对这个问题进行了广泛的研究。
access_type=offline
等API问题已正确实现,否则我不会在Refresh Token
版本中获得localhost
。
我正在使用
requests_oauthlib
python 库。
gcp = OAuth2Session(
app.config['gcp_client_id'],
scope=scope,
redirect_uri=redirect_uri)
# print('Requesting authorization url:', authorization_base_url)
authorization_url, state = gcp.authorization_url(
authorization_base_url,
access_type="offline",
prompt="select_account",
include_granted_scopes='true')
session['oauth_state'] = state
return redirect(authorization_url)
# Next section of code after the browser approves the request
token = gcp.fetch_token(
token_url,
client_secret=app.config['gcp_client_secret'],
authorization_response=request.url)
在
refresh_token
中运行时,令牌具有 localhost
,但在云中运行时则没有。
此 Google 文档讨论了刷新令牌,这表明 Web 应用程序支持此功能。
[更新2018年11月18日]
我发现了这个错误报告,它给了我一个提示来更改我的代码:
authorization_url, state = gcp.authorization_url(
authorization_base_url,
access_type="offline",
prompt="select_account",
include_granted_scopes='true')
对此:
authorization_url, state = gcp.authorization_url(
authorization_base_url,
access_type="offline",
prompt="consent",
include_granted_scopes='true')
现在我在公共服务器版本和本地主机版本中收到刷新令牌。
接下来我搜索了有关
prompt
选项的文档,发现了这个:
提示(可选)
以空格分隔的字符串值列表,指定是否 授权服务器提示用户重新进行身份验证 同意。可能的值为:
无 授权服务器的作用是 不显示任何身份验证或用户同意屏幕;它会返回 如果用户尚未经过身份验证并且尚未进行身份验证,则会出现错误 对所请求范围的预先配置同意。您可以使用 none 来 检查现有的身份验证和/或同意。
同意 授权服务器在返回之前提示用户同意 向客户提供信息。
选择帐户 授权服务器 提示用户选择用户帐户。这允许具有以下权限的用户 授权服务器上的多个帐户可以在其中进行选择 他们可能有多个帐户的当前会话。
如果未指定任何值并且用户之前未授权访问,则 用户会看到同意屏幕。
我认为谷歌文档应该更新。在同一页面上,出现以下文本:
access_type(可选)
允许的值为离线和在线。这 效果记录在离线访问中;如果正在使用访问令牌 请求时,除非离线,否则客户端不会收到刷新令牌 已指定。
该声明给我带来了很多困惑,试图调试为什么我无法获取公共服务器版本的刷新令牌,但可以获取本地主机版本的刷新令牌。
与本地主机版本相比,在 Google Cloud Engine (GCE) 上运行 Python Flask 应用程序时,您似乎遇到了缺少 OAuth 2 刷新令牌的问题。我很高兴看到您已经进行了广泛的研究,并通过将“提示”选项从“select_account”更改为“同意”找到了解决方案。
您对 Google 文档中的差异的观察是有效的,很高兴您已经确定了问题的根源。
最诚挚的问候, 约翰