问题:缺少 OAuth 2 刷新令牌。
问题是 localhost 版本接收 aRefresh Token
作为授予令牌的一部分,但在 GCE 中运行的相同代码没有。
细节:
我编写了一个实现 Google OAuth 2.0 的 Python Flask 应用程序。此 Web 应用程序使用经过验证的域名、有效的 SSL 证书和 HTTPS 端点在云中运行。这个未经修改的 Web 应用程序也可以作为localhost
. 运行时的区别在于 localhost 版本不使用 TLS。代码流没有其他区别。
除了Refresh Token
缺少并且我无法自动更新 a之外token
,一切正常。
我对这个问题进行了广泛的研究。诸如此类的 API 问题access_type=offline
已正确实现,否则我将无法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 授权服务器不显示任何身份验证或用户同意屏幕;如果用户尚未经过身份验证并且尚未为请求的范围预先配置同意,它将返回错误。您可以使用 none 检查现有的身份验证和/或同意。
同意 授权服务器在向客户端返回信息之前提示用户同意。
select_account 授权服务器提示用户选择用户帐户。这允许在授权服务器上拥有多个帐户的用户在他们可能具有当前会话的多个帐户中进行选择。
如果未指定任何值且用户之前未授权访问,则向用户显示同意屏幕。
我认为应该更新谷歌文档。在同一页面上,出现以下文本:
access_type (可选)
允许的值是离线和在线。效果记录在离线访问中;如果正在请求访问令牌,则客户端不会收到刷新令牌,除非指定了脱机。
该声明让我很困惑,试图调试为什么我无法获得公共服务器版本的刷新令牌,但我可以获得 localhost 版本。