Google OAuth всегда показывает экран согласия

Я строю установлены приложение, которое будет иметь функции, требующие Google Drive REST API с использованием Qt и C ++. Я понимаю, что Qt сейчас выпускает новые библиотеки для поддержки потоков OAuth, но давайте предположим, что я студент, и изучение использования OAuth на этом уровне является требованием для этого проекта.

В моем приложении у меня есть рабочий поток OAuth для установленных приложений, который заканчивается токеном доступа и токеном обновления, сохраняемым с помощью QSettings (я открыт для того, чтобы узнать, является ли это катастрофически плохой идеей). Приложение не требует аутентификации / входа в систему ради самого себя / данных, но для аутентификации в Google требуется вызов API с использованием токена доступа. Это приложение не имеет связанных веб-серверных хостов; он прост и должен быть развернут полностью локально (я написал и включил простой TCP-сервер, который получит авторизацию redirect_uri и будет запускаться и закрываться при вызове из приложения).

Поэтому мне интересно узнать, как лучше всего убедиться, что, когда пользователь открывает мое приложение и хочет использовать функции Google Диска, они соответствующим образом проходят проверку подлинности на стороне Google. Скажем, если я поддерживаю токен доступа в реестре, и этот токен доступа предоставляется для каждого пользователя / приложения (верно?), То как я могу убедиться, что только пользователь, которому принадлежит токен, может совершать вызовы? API с этим?

Вот мое понимание и подход; не стесняйтесь поправлять меня или обучать меня, если я неправильно понял.

Если токен доступа найден, выполните следующее:

  1. Откройте страницу браузера в домене входа в Google и попросите пользователя пройти аутентификацию (это может помешать пользователю использовать сеанс кэшированного входа в систему, который будет иметь доступ к токену, к которому в противном случае он не должен был бы иметь доступ)
  2. Если пользователь правильно прошел аутентификацию в учетной записи Google, верните управление приложению и выполните тестовый вызов API с помощью сохраненного токена.
  3. Если вызов не удается (отвечает invalid_credentials) Я должен быть уверен, что это так, потому что срок действия токена доступа истек, и приложение выполнит процедуру обновления токена доступа с помощью токена обновления.

Если токен доступа изначально не найден:

  1. Запустите нормальный OAuth-установленный поток приложений
  2. Получите токены и сохраните их, чтобы при следующем открытии приложения пользователем использовалась прежняя процедура

Моя проблема — первые два шага, если токен доступа найден. Номинально это может быть сделано обычным потоком OAuth, но кажется, что при использовании localhost в качестве URI перенаправления, Google всегда будет запрашивать согласие, независимо от настроек для prompt а также access_type параметры запроса авторизации.

Что можно сделать, чтобы выполнить эти первые два шага таким образом, чтобы мое приложение могло управлять им (т. Е. Не решение, которое опирается на сервер, расположенный где-то на бэкэнд-сервере)?

Если этот вопрос слишком открытый для требований SO, я могу сделать еще несколько ограничений / предположений, чтобы ограничить проблемную область, но я бы предпочел этого не делать в случае, если я по незнанию выберум хорошее жизнеспособное решение.

Спасибо за прочтение! Извините, если это многословно; Я хотел убедиться, что мой проблемный домен был полностью выделен!

1

Решение

Если вы используете установленное приложение, я бы не рекомендовал использовать или хранить токены обновления. Хранение токенов обновления на стороне клиента означает, что если злоумышленник получит доступ к клиентскому приложению, он получит неограниченный доступ к пользовательскому приложению без необходимости ввода учетных данных пользователя. Если вы настаиваете на получении токена обновления, убедитесь, что вы следуете поток установленных приложений, с code_verifier Параметр включен в ваши запросы.

Если маркер доступа найден, вам следует попробуй проверить это, и если проверено, то используйте его на Google API, в противном случае вынудите пользователя снова войти в систему (или обновите его, если вы все еще решили использовать токены обновления).

Если токен доступа не найден, твой поток звучит нормально.

Несколько замечаний по входу в систему с Google:

  1. Google вернет обновленный токен, только если вы укажете access_type=offline в вашем запросе авторизации.
  2. Google будет возвращать токен обновления только при первом запросе авторизации пользователя, если вы не укажете prompt=consent в параметрах вашего запроса.
  3. По моему опыту, когда опуская prompt Параметр запроса, пользователь больше не запрашивается для их согласия. Если они вошли в Google, вы получите новый токен доступа, но без обновления токен, если у вас нет prompt=consent,
  4. Я думаю, что идея, которую вы используете prompt=consent если у вас нет записи о том, что пользователь когда-либо использовал ваше приложение. В противном случае, если они использовали его раньше, вы можете просто prompt=none,

Это всего лишь мое понимание всего этого.

0

Другие решения

Мой подход, который я в итоге использовал, состоял в том, чтобы просто развернуть базу данных SQLite, которая будет храниться в роуминг-каталоге AppData. Схема БД включает в себя поле для имени пользователя (из поля IDIDoken OpenID, если оно существует), URL-адрес изображения пользователя (снова из IDToken, если он существует), строки токенов обновления и доступа (будут сохранены в виде зашифрованных строк, когда я получу вокруг), UID / подстрока пользователя и поле для имени пользователя и пароля.

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

  • Если они существуют и верны, пользователь войдет в систему и получит доступ к соответствующему токену доступа и обновления.
  • Если пользователь забыл свой пароль, его попросят о повторном согласии (повторная проверка потока установленного приложения), и любой пароль, который он предоставил при первоначальном входе в систему, будет использоваться в качестве пароля для сброса. Для моих целей считается, что вход в Google для потока установленных приложений является достаточным доказательством того, что учетная запись пользователя принадлежит им, и у них должна быть авторизация для сброса пароля.
  • Если пользователь новый пользователь и не имеет записи в локальном файле базы данных SQLite, он также может нажать кнопку «Создать новую учетную запись», которая также эффективно проходит процесс авторизации, но на этот раз совершенно новый запись отправляется в базу данных SQLite с заполненными соответствующими полями.

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

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

Еще раз спасибо!

0

По вопросам рекламы [email protected]