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


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

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

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

вот как я представлял себе его работу:

  1. пользователь запрашивает приложение, чтобы получить доступ к его личным данным.
  2. приложение использует Android AccountManager класс для запроса маркера доступа для 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. Уютные!".

так как же мне это сделать? И, пожалуйста, не говорите "использовать OpenID" или "не использовать OAuth2" или другие подобные бесполезные ответы. О, и я ... очень хотелось бы продолжать использовать nice AccountManager UI, а не дерьмовое всплывающее окно WebViews

Edit

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

обновление

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

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

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

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

6 59

6 ответов:

вам, вероятно, нужно OpenId Connect, который использует токены OAuth для аутентификации. Что касается AccountManager, текущая поддержка OAuth немного хаки, новый Google Play Services, набор, который будет выпущен "скоро", должен, надеюсь, сделать это лучше. Смотрите здесь для демо.

Я только что написал ответ к аналогичному вопросу StackOverflow.

Google называет это Гибридные Приложения и объясняет, как "Android приложение получает автономный доступ для веб-серверной части".

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

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

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

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

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

вот несколько вещей, которые я нашел полезным при работе с токенами. Первый-это конечная точка Google tokeninfo. Сам токен является просто base64-кодированным JSON. Это означает, что он не зашифрован, поэтому вам нужно обязательно использовать 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. Это было полезно для меня, потому что я начал понимать, как работают разные вещи в консоли Google API вместе:

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

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

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

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

в двух словах в чем разница от использования запроса oauth2 getAuthToken и getToken

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

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

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

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