Токен обновления Google OAuth 2 отсутствует для веб-приложения, но присутствует для локального хоста

Проблема: отсутствует токен обновления OAuth 2.

Проблема в том, что локальная версия получает Refresh Token как часть предоставленного токена, но тот же код, работающий в GCE, этого не делает.

Подробности:

Я написал приложение Python Flask, которое реализует Google OAuth 2.0. Это веб-приложение работает в облаке с проверенным доменным именем, действительным сертификатом SSL и конечной точкой HTTPS. Это немодифицированное веб-приложение также работает как localhost. Отличия среды выполнения в том, что версия для локального хоста не использует TLS. Других отличий в потоке кода нет.

За исключением того, что Refresh Token отсутствует, и я не могу автоматически обновить token, все работает отлично.

Я тщательно исследовал этот вопрос. Проблемы API, такие как access_type=offline и т. д., реализованы правильно, иначе я бы не получил Refresh Token в версии localhost.

Я использую библиотеку Python 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.2018]

Я нашел этот отчет об ошибке, который дал мне подсказку изменить мой код:

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 и нашел это:

запрос OpenID Conect

подсказка (необязательно)

Разделенный пробелами список строковых значений, указывающий, будет ли сервер авторизации запрашивать у пользователя повторную аутентификацию и согласие. Возможные значения:

нет Сервер авторизации не отображает никаких экранов проверки подлинности или согласия пользователя; он вернет ошибку, если пользователь еще не аутентифицирован и не имеет предварительно настроенного согласия для запрошенных областей. Вы можете использовать none для проверки существующей аутентификации и/или согласия.

согласие Сервер авторизации запрашивает у пользователя согласие, прежде чем вернуть информацию клиенту.

select_account Сервер авторизации предлагает пользователю выбрать учетную запись пользователя. Это позволяет пользователю, имеющему несколько учетных записей на сервере авторизации, выбирать из нескольких учетных записей, для которых у него могут быть текущие сеансы.

Если значение не указано и пользователь ранее не авторизовал доступ, пользователю отображается экран согласия.

Я думаю, что документация Google должна быть обновлена. На той же странице появляется следующий текст:

access_type (необязательно)

Допустимые значения: offline и online. Эффект задокументирован в автономном доступе; если запрашивается токен доступа, клиент не получает токен обновления, если не указан автономный режим.

Это утверждение вызвало у меня много путаницы при попытке отладки, почему я не мог получить токен обновления для версии общедоступного сервера, но мог для версии локального хоста.


person John Hanley    schedule 16.11.2018    source источник
comment
Используете ли вы разных пользователей для тестирования локальных и облачных версий?   -  person Kavindu Dodanduwa    schedule 19.11.2018
comment
@KavinduDodanduwa Нет. Я тестировал с одним и тем же набором учетных данных и теми же ролями - меняя их контролируемым образом, чтобы понять это.   -  person John Hanley    schedule 19.11.2018
comment
Можете ли вы изменить пользователя для облачного развертывания и тестирования? Я имею в виду создание нового пользователя и попытку получить токены? У Google странная политика в отношении токенов обновления. Если правильные параметры не указаны, G выдает только токен обновления в первый раз.   -  person Kavindu Dodanduwa    schedule 19.11.2018
comment
@KavinduDodanduwa Я тестирую несколько идентификаторов. Смотрите мой следующий комментарий.   -  person John Hanley    schedule 19.11.2018
comment
@KavinduDodanduwa - я видел отчет об ошибке на github. Если я перейду с prompt=select_account на prompt=consent, я получу токен обновления. Я еще не тестировал это широко. Вот ссылка: github.com/googleapis/oauth2client/issues/453   -  person John Hanley    schedule 19.11.2018
comment
Если кто-то знает подробности различий между prompt=select_account и prompt=consent и любыми другими вариантами, опубликуйте ответ со ссылками. Я награжу награду за лучший ответ, определяющий эту проблему.   -  person John Hanley    schedule 19.11.2018
comment
Я думаю, что это ответ на это - stackoverflow.com/a/10220362/3197055   -  person Kavindu Dodanduwa    schedule 19.11.2018
comment
Как указано выше в ответе, нам нужно принудительно получить согласие на получение токена обновления. Но я уверен, что вы получите это в первый раз.!   -  person Kavindu Dodanduwa    schedule 19.11.2018
comment
@KavinduDodanduwa Ссылка на отчет об ошибке отличается от вашей ссылки (которая, я думаю, предшествует v2). Я думаю, что переход на v2 внес изменения в опции. Я все еще пытаюсь понять это и задокументировать, что именно не так и какова правильная реализация.   -  person John Hanley    schedule 19.11.2018
comment
@KavinduDodanduwa Я пытался использовать новую учетную запись. Фактически, в течение этого периода отладки я также настроил Google Identity и протестировал новых пользователей, созданных с помощью этой службы. Те же результаты.   -  person John Hanley    schedule 19.11.2018
comment
@KavinduDodanduwa - еще один предмет. Моя учетная запись GCP является организацией G Suite. Я не уверен, что это имеет значение.   -  person John Hanley    schedule 19.11.2018
comment
Если это так, то это вполне может быть ошибкой. Я предполагаю, что у них есть конфликт между prompt=select_account и согласием. Но, как я уже говорил, developers.google.com/identity/protocols/ выделяет первый выпуск токена обновления. Просто сначала найдите слово, и вы его увидите :)   -  person Kavindu Dodanduwa    schedule 19.11.2018
comment
@KavinduDodanduwa - с согласия теперь я каждый раз получаю токен обновления - как для версии для локального хоста, так и для общедоступной версии. С select_account я получаю токен обновления только для локального хоста и никогда с общедоступной версией (новая учетная запись, первый вход в систему и т. д.). Завтра я протестирую обновление, отзыв и т. д. и попытаюсь лучше понять, что на самом деле означает это изменение.   -  person John Hanley    schedule 19.11.2018
comment
@KavinduDodanduwa - существует странное поведение, связанное с вашим комментарием о первом выпуске токена обновления. У меня сегодня вечер воскресенья, завтра я займусь этим подробнее. Я обновил свой вопрос новой информацией, которую я знаю на данный момент. Я еще не уверен, что решил проблему.   -  person John Hanley    schedule 19.11.2018
comment
Да, пожалуйста, взгляните на это свежим взглядом. Я уверен в первом выпуске токена обновления. Но все же я не уверен в поведении, когда для приглашения установлено значение select_account. И снова ничто не может объяснить разницу в развертывании на локальном хосте и в облаке, которую вы наблюдаете.   -  person Kavindu Dodanduwa    schedule 19.11.2018
comment
Вероятно, связано: stackoverflow.com/questions/11475101/   -  person Martin Zeitler    schedule 20.06.2020
comment
Возвращаясь к основам, какие API Google вы используете в своем приложении Flask с GCE? Причина, по которой я спрашиваю, заключается в том, что только определенные API Google требуют разрешений пользователя. Также любопытно, почему вы запускаете свое приложение на GCE, а не на GAE или GCR,   -  person wescpy    schedule 03.08.2020
comment
@wescpy - решение находится в последней части моего вопроса. Что касается вашего комментария, ни один из ваших вопросов не относится к токенам OAuth. Мне неизвестны какие-либо API Google, для которых не требуется разрешение (учетная запись пользователя и/или службы). Ключ запрашивал offline доступ при аутентификации учетной записи пользователя.   -  person John Hanley    schedule 03.08.2020
comment
Вы используете токены обновления ТОЛЬКО с идентификаторами клиентов OAuth (авторизация пользователя), то есть API, получающие доступ к данным, принадлежащим пользователям (именно поэтому я спросил, какие API вы используете), т. е. обычно API G Suite или YT. Аутентификация сервисного аккаунта наиболее распространена с API-интерфейсами GCP, поскольку эти данные обычно принадлежат приложениям/проектам, а не человеку — такой доступ не требует токенов обновления. Существует также третий тип учетных данных — ключ API. Это используется всеми API Карт, простым поиском YT и многими API GCP ML, поскольку они получают доступ к общедоступным данным, данным, не принадлежащим ни пользователям, ни приложениям. Поскольку это не OAuth, для них нет токенов доступа или обновления.   -  person wescpy    schedule 03.08.2020
comment
@wescpy - я не уверен, как ваши комментарии относятся к offline доступу`. Я очень хорошо понимаю OAuth в GCP. Я Google GDE с внутренним доступом. Я предлагаю вам создать вопрос и самостоятельно ответить. Этой теме почти два года. Что касается ключей API, то теперь они считаются устаревшими, и Google постепенно отказывается от них. Ваша причина использования учетных записей служб по сравнению с учетными записями пользователей неверна. Право собственности на данные не имеет отношения к тому, какой метод следует использовать.   -  person John Hanley    schedule 03.08.2020