Токен обновления Google OAuth 2 отсутствует для веб-приложения, но присутствует для localhost
Проблема: Отсутствует OAuth 2 Обновить маркер.
Проблема в том, что версия localhost получает Refresh Token
как часть предоставленного токена, но тот же код, работающий в GCE, не.
Подробности:
Я написал приложение Python Flask, которое реализует Google OAuth 2.0. Это веб-приложение работает в облаке с проверенным доменным именем, действительным сертификатом SSL и конечной точкой HTTPS. Это веб-приложение без изменений также работает как localhost
, Разница между средой выполнения заключается в том, что версия localhost не использует TLS. Других различий в потоке кода нет.
Кроме Refresh Token
отсутствует, и я не могу автоматически обновить token
все работает отлично.
Я тщательно исследовал эту проблему. Проблемы API, такие как access_type=offline
и т. д. правильно реализованы, иначе я бы не получил Refresh Token
в localhost
версия.
Я использую requests_oauthlib
библиотека питонов.
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 обсуждаются токены обновления, которые указывают, что это поддерживается для веб-приложений.
Обновление токена доступа (автономный доступ)
[Обновление 18.11.08]
Я нашел этот отчет об ошибке, который дал мне подсказку, чтобы изменить мой код от этого:
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')
Теперь я получаю токен обновления в общедоступной версии сервера и в версии localhost.
Затем я искал документацию на prompt
вариант и нашел это:
подсказка (необязательно)
Разделенный пробелами список строковых значений, который указывает, запрашивает ли сервер авторизации пользователя для повторной аутентификации и согласия. Возможные значения:
none Сервер авторизации не отображает экраны аутентификации или согласия пользователя; он вернет ошибку, если пользователь еще не аутентифицирован и не имеет предварительно настроенного согласия для запрошенных областей. Вы не можете использовать ни один, чтобы проверить существующую аутентификацию и / или согласие.
Согласие Сервер авторизации запрашивает согласие пользователя перед возвратом информации клиенту.
select_account Сервер авторизации предлагает пользователю выбрать учетную запись пользователя. Это позволяет пользователю, имеющему несколько учетных записей на сервере авторизации, выбирать среди нескольких учетных записей, для которых они могут иметь текущие сеансы.
Если значение не указано и пользователь не имеет ранее авторизованного доступа, пользователю будет показан экран согласия.
Я думаю, что документация Google должна быть обновлена. На этой же странице появляется следующий текст:
access_type (необязательно)
Допустимые значения: офлайн и онлайн. Эффект задокументирован в автономном доступе; если запрашивается токен доступа, клиент не получает токен обновления, если не указан автономный режим.
Это утверждение вызвало у меня большую путаницу, когда я пытался отладить, почему я не смог получить токен обновления для общедоступной версии сервера, а смог сделать версию для локального хоста.