Аутентификация с помощью OAuth2 для приложения * и * веб-сайта

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

Google заявляет, что «вы можете использовать систему аутентификации Google как способ аутсорсинга аутентификации пользователей для своего приложения, что может исключить необходимость создания, поддержки и защиты хранилища имени пользователя и пароля». Что я и хочу делать. Однако, когда я просматриваю все их примеры и многое другое, я могу найти материал о том, что веб-сайт или приложение аутентифицируют пользователя в отношении сервисов Google.

И действительно, когда я отправляюсь регистрировать свое приложение («клиент») с OAuth2 от Google, есть варианты для клиентов веб-сайта и «установленных» клиентов (например, мобильного приложения), но не для обоих. Я могу создать двух отдельных клиентов, но я прочитал проект OAuth2, и я думаю, что будет проблема, которую я сейчас объясню.

Вот как я это делал:

Блок-схема OAuth2

  1. Пользователь запрашивает у MyApp доступ к своим личным данным.
  2. Приложение использует класс AccountManager Android для запроса токена доступа для API Google.
  3. Android говорит пользователю: «Приложение MyApp хочет получить доступ к вашей базовой информации в Google. Это нормально?»
  4. Пользователь говорит «да».
  5. AccountManager подключается к серверу OAuth2 Google, используя учетные данные, хранящиеся на телефоне, и запрашивает токен доступа.
  6. Возвращается токен доступа (который следует за зелеными линиями).
  7. AccountManager возвращает токен доступа в MyApp.
  8. MyApp отправляет запрос на MySite для личных данных пользователя, включая токен доступа.
  9. MySite необходимо проверить пользователя, используя токен доступа. Он проверяет токен, как описано здесь , с Google – «Google, этот токен действителен?».
  10. Теперь я хочу, чтобы Google сказал: «Да, тот, кто дал это вам, действительно тот пользователь.», Но то, что я думаю, действительно произойдет (на основе проекта OAuth2 и документации Google), будет сказано: «Нет Этот токен действителен только для MyApp, а вы – MySite. GTFO! ».

Итак, как мне это сделать? И ПОЖАЛУЙСТА не говорите «Использовать OpenID» или «Не использовать OAuth2» или другие подобные бесполезные ответы. О, и я бы очень хотел, чтобы использовать хороший пользовательский интерфейс AccountManager а не crappy popup WebView s

редактировать

Предварительный ответ (я отчитаюсь, если это сработает!) От Николая – это то, что он действительно должен работать, а серверам Google будет все равно, откуда появился токен доступа. Кажется, мне немного небезопасно, но я увижу, работает ли это!

Обновить

Я реализовал этот шаблон с Facebook вместо Google, и он полностью работает. Сервер OAuth2 не заботится о том, откуда появился токен доступа. По крайней мере, Facebook не делает этого, поэтому я полагаю, что Google тоже.

В свете этого очень плохой идеей хранить токены доступа! Но мы также не хотим, чтобы нажимать на серверы Facebook / Google, чтобы проверить подлинность для каждого запроса, так как он замедлит все. Вероятно, лучше всего добавить дополнительный cookie-файл проверки подлинности для вашего сайта, который вы раздаете, когда их токен доступа проверен, но более простым способом является просто обработать токен доступа, как пароль, и сохранить его. Вам не нужно его солить, поскольку токены доступа действительно очень длинные. Таким образом, вышеприведенные этапы выглядят примерно так:

9. MySite необходимо проверить пользователя, используя токен доступа. Сначала он проверяет свой кеш с хэшированными действительными токенами доступа. Если хэш жетона найден там, он знает, что пользователь аутентифицирован. В противном случае он проверяет с помощью Google, как описано здесь , с Google – «Google, этот токен действителен?».

10. Если Google говорит, что токен доступа неверен, мы указываем пользователю GTFO. В противном случае Google говорит: «Да, это действительный пользователь», и затем мы проверяем нашу зарегистрированную базу данных пользователей. Если это имя пользователя Google (или идентификатор Facebook при использовании Facebook) не найдено, мы можем создать нового пользователя. Затем мы кэшируем хешированное значение токена доступа.

Вероятно, вам нужен OpenID Connect, который использует токены OAuth для аутентификации. Что касается AccountManager , текущая поддержка OAuth немного взломана, новые сервисы Google Play , которые будут выпущены «скоро», должны надеяться сделать это лучше. См. Здесь демо .

Я просто отправил ответ на аналогичный вопрос StackOverflow.

Google вызывает эти гибридные приложения и объясняет, как «Android-приложение получает автономный доступ для веб-back-end» .

Суть его в том, что вам нужно передать GoogleAuthUtil.getToken в GoogleAuthUtil.getToken , чтобы заставить его вернуть код авторизации (а не токен OAuth2). Этот код авторизации можно передать из вашего мобильного приложения на ваш сервер и обменять на токен OAuth2 и токен обновления, согласно этой схеме .

Параметр scope должен выглядеть примерно так:

 oauth2:server:client_id:<your_server_client_it>:api_scope:<scope_url_1> <scope_url_2> ... 

Вы можете использовать токен доступа, полученный мобильным приложением в другом месте. Drive SDK имеет приятное и простое введение, которое проходит через поток https://developers.google.com/drive/quickstart-android

По крайней мере, с Google, токен доступа в конце концов истекает. Вот почему у Android AccountManager есть метод invalidateAuthToken – токен кэшированного доступа истек, и вам нужно сказать, что AccountManager перестает давать вам старый, а вместо этого получает новый. Это делает несколько более безопасным кэширование токена, поскольку сам токен не дает вам вечного доступа как этого пользователя. Вместо этого, когда он действителен, он просто говорит: «В какой-то момент недавнего прошлого этот токен был приобретен доверенным источником».

Вот несколько вещей, которые я нашел полезными при работе с токенами. Первая – конечная точка Google tokeninfo. Сам токен – это только JSON с кодировкой base64. Это означает, что он не зашифрован, поэтому вы должны быть уверены, что используете HTTPS для связи. Однако это также означает, что вы можете изучить токен и лучше понять, что происходит.

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=

Если ваш токен был «abcdef», вы должны перейти к:

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=abcdef

И Google распакует токен для вас. Это простой объект JSON, который включает поле «expires_in», в котором указывается количество секунд, для которых токен все еще действителен. В 6:03 в видео ниже вы можете увидеть распакованный токен:

https://developers.google.com/events/io/sessions/383266187

Это видео включает в себя подробный обзор OAuth2 и стоит посмотреть в полном объеме, если вы собираетесь иметь дело с OAuth и токенами. Оратор также обсуждает другие формы токенов Oauth2, которые не являются токенами доступа, которые не истекают.

Еще одним полезным ресурсом является игровая площадка OAuth. Это позволяет делать основные вещи, такие как области запросов, составлять запросы и возвращать токены. Эта ссылка, похоже, работает спорадически, и в Chrome мне пришлось установить приложение Oauth Playground:

https://developers.google.com/oauthplayground/

И вот учебник Тима Брея, докладчика на видео, объясняющего, как использовать токены доступа для связи с сервером из приложения для Android. Это было полезно для меня, потому что я начал понимать, как разные вещи в консоли API Google работают вместе:

http://android-developers.blogspot.in/2013/01/verifying-back-end-calls-from-android.html

Что касается фактического ответа на ваш вопрос, я бы сказал, что вам никогда не нужно кэшировать токен доступа на сервере. Как пояснялось выше в разделе «Проверка обратных вызовов от Android», проверка токена почти всегда является быстрым статическим вызовом, то есть нет причин для кэширования токенов:

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

Наконец, вы действительно можете использовать AccountManager для доступа к токенам доступа. Однако вместо этого Google вместо этого рекомендует использовать класс GoogleAuthUtil в библиотеке Play Services:

Вкратце, в чем отличие от использования запроса OAuth2 getAuthToken и getToken

Здесь обратите внимание на комментарий Тима Брея, того же парня, который снова появился из вышеупомянутых ссылок, заявив, что они прилагают свои усилия к маршруту GoogleAuthUtil . Обратите внимание, однако, что это означает, что вы будете ограничены аутентификацией Google. Я считаю, что AccountManager может быть использован для получения, например, токена Facebook, а не с GoogleAuthUtil .

Он точно описывает, что вы хотите: https://developers.google.com/identity/protocols/CrossClientAuth

Когда нам нужно было что-то делать на сервере OAuth без Google, мы сохранили токены в базе данных на веб-сайте. Затем приложение будет использовать веб-службы для запроса маркера, когда это необходимо для запроса данных.

Пользователь может выполнять регистрацию OAuth либо в Интернете, либо в приложении. Они поделились одним и тем же токеном приложения, чтобы они могли использовать один и тот же токен доступа. После регистрации мы будем хранить токены доступа и обновления в БД для использования с нужным ей приложением.

Intereting Posts
Appinvite_styles.xml: 5: ошибка При включении библиотеки Google Play Services для затмения Труба в `adb shell` Android: Есть ли в любом случае, чтобы получить емкость аккумулятора устройства в махе? Режим отладки в телефоне и подписка с лицензионным ключом Страница разработчика Android: понимание примера профилирования traceview Как разделить две кнопки в LinearLayout Удаляет ли приложение андроида удаление базы данных, хранящейся на SD-карте? Com.android.builder.packaging.DuplicateFileException: дублированные файлы, скопированные в APK META-INF / maven / com.fasterxml.jackson.core / jackson-databind / pom.xml ListView не расширяется внутри NestedScrollView Настройка цвета фона элемента макета Android «Ожидаемый ресурс меню типа» при раздувании MenuButton Как остановить сборщик мусора Android? Является ли это возможным? Правый подход Android: где JSON-ответ должен анализироваться – в потоке пользовательского интерфейса или в другом? Обнаружение изменения местоположения веб-браузера Android Неверный размер экрана заставки