Пользователь
0,0
рейтинг
19 июня 2012 в 18:51

Разработка → OAuth на практике. Аутентификация и авторизация пользователей сайта через популярные социалки

Думаю, не мне одному чрезвычайно надоели ресурсы, требующие регистрации по каждому поводу и без. С обязательной капчей, которая правильно введется только с пятого раза, с подтверждением по е-мейлу, которое обязательно свалится в спам и то — только через сутки. Придумывать каждый раз новую пару логин-пароль — забудется, вводить одно и то же на всех сайтах — небезопасно. Местами прокатывают пары вида «qwerty:qwerty» или «login:password», но, увы, далеко не везде. Надоело. Не счесть, сколько раз я, увидев надпись «только зарегистрированный пользователь может ****», просто кривился и закрывал вкладку, чтобы больше ни разу на этот сайт не заходить. Неужели администраторы ресурсов сами этого не понимают? А ведь технологии OAuth уже 6 лет, и 90% процентов интернет-аудитории имеет аккаунт минимум на одном из ресурсов, поддерживающих OAuth. Так почему кнопки «Войти через» нет на каждом ресурсе? Я установил опрос у себя на сайimageте. Проголосовало немного (далеко не все мои пользователи имеют собственный сайт с регистрацией), но достаточно, чтобы появилась мысль написать эту статью, в надежде, что сайтов, использующих OAuth для авторизации, станет больше. Потому что:
  • Это не сложная технология. Смею надеяться, что каждый, нашедший в себе силы прочитать статью до конца, сможет самостоятельно прикрутить OAuth к своему сайту за 1-2 дня.
  • OAuth базируется на HTTP. Большинство сервис-провайдеров даже цифровой подписи не требуют, т.е., кроме собственно возможности создавать GET и POST запросы — ничего не надо, а простота протокола позволяет написать OAuth-клиент «на коленке» буквально за час. Без каких-то специальных библиотек.
  • Так они и зарегистрируются у вас! Просто используют для этого свои логин-пароль на другом сайте. Сервис-провайдеры не предоставляют какую-то специфическую характеристику пользователя, необходимую на вашем сайте? Так запросите эту характеристику при первом визите и всех делов. В остальном — пользователь, вошедший через OAuth, ничем не отличается от зарегистрировавшихся обычным путем.
  • Я не ставил целью подробно описать протокол OAuth и его возможности. Это все уже написано неоднократно, например, здесь и здесь. Я хочу дать примеры практической реализации OAuth для наиболее распространенных социалок рунета без привязки к конкретному языку.
  • Ну а что касается 7%, которым OAuth не нужен — если 93 из ста прочитавших этот пост админов внедрят OAuth у себя на сайте, я буду более чем доволен :)


Почему OAuth, а не OpenID?

Потому что OpenID практически бесполезен для тех целей, для которых декларирован. Это сугубо мое мнение, но оно опирается не на пустое место.
Во-первых, OpenID пользуются в основном «гики», процент которых в интернете не настолько высок, чтобы перестраивать под них сайты (за некоторым исключением, разумеется :) ) Почему так? Потому что для того, чтобы получить OpenID аккаунт, надо — его получить. Зайти на OpenID сервер и предпринять некоторые действия, чтобы заполучить некий, довольно невразумительный, набор символов. Который, несмотря на сложность (для простого пользователя) надо не забыть и вводить при случае, если на глаза попадется знакомая пиктограмма image. Ну какой казуальный пользователь будет это делать? А с OAuth все намного проще — видит человек кнопку «Войти через ВКонтакте», нажимает, и… уже на сайте с правами зарегистрированного пользователя. «Будьте проще», — говорил классик, — «и люди к вам потянутся». Как в воду глядел.
Во-вторых, возможности OAuth далеко не исчерпываются аутентификацией и авторизацией. Получив в процессе авторизации токен, его можно использовать для дальнейшей интеграции возможностей социалки в свой ресурс — чтение/написание постов, доступ к френдленте и стене и многое другое.
В-третьих, OpenID активно пользуются спамеры и хакеры. Зачастую реализация OpenID аутентификации на ресурсе делается без особого внимания к известным его уязвимостям — по одному только описанию протокола на OpenID-провайдере или с помощью неизвестно кем и когда написанной библиотеки. К примеру, многие сайты не требуют со входящих по OpenID ввода капчи. И ничто не мешает злоумышленнику поднять свой OpenID-сервер, который будет подтверждать любой идентификатор и начать спамить доверчивый сайт автоматически сгенеренными идентификаторами. Кроме того, OpenID аутентификация, в сущности, не дает никаких гарантий клиенту. Она подтверждает лишь, что запрашиваемый пользователь действительно зарегистрирован на одном из OpenID-серверов — и все. Механизмы получения дополнительной информации о пользователе (email, имя, возраст) имеются, но мало кем поддерживаются. Можно, конечно, в нарушение идей OpenID, анализировать идентификатор и доверять только определенным OpenID-провайдерам (например, тем же социалкам). Но смысл, если почти все из них (за исключением ЖЖ, но он и по OpenID ровным счетом ничего не расскажет о пользователе) поддерживают OAuth, который позволяет получить намного больше информации? Так что со всех своих сайтов я вообще убрал поддержку OpenID.

Почему OAuth, а не виджет «Войти через»?

Нет проблем. Если вас устраивают функционал, дизайн и уровень безопасности виджета — то его воткнуть в код на самом деле намного проще — можете дальше не читать.

Как это работает.

Если кому интересны все подробности, то см. ссылки выше. А вкратце — так:
  1. Заходите на сервис-провайдер ХХХ, регистрируете там свой сайт, получаете код клиента и секретный код.
  2. По нажатию кнопки на вашем сайте «войти через ХХХ» производится обмен запросами с сервером XXX, перенаправление пользователя на ХХХ для ввода пароля, логина и подтверждения передачи данных на ваш сайт и получения токена, с помощью которого у сервера ХХХ можно запросить дополнительные данные о пользователе. Конкретика зависит от реализации OAuth на сервис-провайдере — поддерживаемой версии протокола, поддерживаемых потоков и пр.
  3. С помощью полученного токена с сервера ХХХ получаются имя, емайл, дата рождения, аватар и прочая информация, которая обычно и требуется при регистрации. После этого можно вызывать стандартную функцию по добавлению нового пользователя.


Почему сырой HTTP, а не куски кода с использованием OAuth библиотеки?

Потому что я порядком помучался, вытаскивая этот самый сырой HTTP зачастую и из кусков кода, иллюстрирующих использование той или иной библиотеки. Конкретная реализация OAuth на каждом сервере имеет свои тонкости, перед которыми может спасовать даже самая гибкая библиотека. Кроме того, веб-языков много, библиотек — еще больше, дать примеры на все просто нереально. А сырого HTTP (при наличии мозгов) вполне достаточно для использования любой библиотеки. Чего не скажешь об обратном случае.

Практические рекомендации по реализации

Разумеется, в первую очередь надо зарегистрироваться в соцсети, активировать аккаунт, ну и всё такое. Не торопиться. Некоторые сервера не сразу корректно обрабатывают запросы от свежезарегистрированных OAuth-клиентов. Здесь я расписал только успешные потоки, забывать про обработку ошибок — никак не стоит. Также я практически не уделил внимания аспектам безопасности — это тема отдельной статьи. Как минимум, везде, где можно передавать уникальный параметр в callback-url для каждого пользователя — это стоит делать (Основной callback адрес должен оставаться без изменений, а меняться — только параметр, иначе сервер не пропустит запрос. Особо обратите на это внимание, если у вас стоит mod_rewrite), как и пользоваться параметром state для передачи дополнительных данных callback-скрипту (там, где этот параметр поддерживается). Я все это пока оставил за скобками.

imageВКонтакте
1. Идем сюда. Тип — «Веб-сайт». Вводим базовый домен и адрес сайта. На странице настроек получаем client_id (ID приложения) и secret_key (защищенный ключ). image2. Втыкаем в код кнопку вида
<a href="http://oauth.vk.com/authorize?client_id={client_id}&redirect_uri=mysite.com/vklogin&response_type=code" title="Зайти через ВКонтакте">Зайти через ВКонтакте</a>
Почему response_type=code, а не token? Потому что некоторые ресурсы не поддерживают response_type=token. Что такое vklogin? Это скрипт, который должен будет обработать ответ от сервера ВКонтакте, получить от него токен и добыть информацию о пользователе.
3. Что делает vklogin?
3.1. vklogin получает в get-параметрах (прямо в строке запроса) результаты авторизации. В случае успеха
http://mysite.com/vklogin?code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a
В случае неудачи
http://mysite.com/vklogin?error=invalid_request&error_description=Invalid+display+parameter
Соответственно, первым делом скрипт анализирует наличие code, достает этот параметр и выполняет
3.2. https-запрос (протоколом полагается POST, но ВКонтакте используется GET. Разницы немного, но имейте в виду) вида:
GET https://oauth.vk.com/access_token?client_id={client_id}&client_secret={secret_key}& code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a//полученный в параметрах код
3.3. и анализирует ответ. Любой ответ, кроме 200 OK сигнализирует об ошибке. В случае успеха мы получаем в теле ответа список параметров в формате JSON, содержащий access_token и user_id. После чего (мы же регистрируем пользователя) выполняется еще один GET запрос — обращение к методу users.get API ВКонтакте:
GET https://api.vk.com/method/users.get?uids={user_id}&fields=uid,first_name,last_name,nickname,screen_name,sex,bdate,city,country,timezone,photo&access_token={access_token}
3.4. В ответ на это (опять же в случае успеха) мы получаем опять-таки JSON список перечисленных параметров. Что нам и нужно было. Имя пользователя — в utf8, город и регион — в виде кодов, названия надо получать вызовом отдельного метода с укаазнием кода.
Полный список того, чего можно запросить, можно взять здесь. Полный список методов API ВКонтакте здесь.

imageОдноклассники
1. Регистрируемся как разработчик здесь. Идем сюда и заполняем заявку на получение OAuth доступа. Н-да. Заявка, похоже, обрабатывается вручную. Если ответа в течение суток нет, пинаем поддержку по тому же адресу. «Одноклассники», что тут скажешь...
2. Получаем письмо с инструкциями и, следуя им, заполняем форму.image
Все заполненные в примере поля обязательны к заполнению. Нажимаем «Сохранить» и получаем письмо на указанный емайл, содержащее client_id(Application ID), public_key(Публичный ключ приложения) и secret_key(Секретный ключ приложения)
3. Код кнопки должен быть вида:
<a href="http://www.odnoklassniki.ru/oauth/authorize?client_id={client_id}&response_type=code&redirect_uri=http://mysite.com/oklogin" title="Одноклассники">Войти через Одноклассников</a>
4. oklogin
3.1. Анализируем строку на наличие code.
3.2. Выполняем POST запрос на:
http://api.odnoklassniki.ru/oauth/token.do
с параметрами в теле запроса:
code={code}&redirect_uri=http://mysite.com/oklogin&grant_type=authorization_code&client_id={client_id}&client_secret={secret_key}
3.3. Получаем JSON список параметров, содержащий access_token. выполняем GET-запрос:
GET http://api.odnoklassniki.ru/fb.do?method=users.getCurrentUser&access_token={access_token}&application_key={public_key}&sig={sign}
sign — трахнутая на все байты md5-подпись
sign=hex_md5('application_key={public_key}method=users.getCurrentUser'+hex_md5({access_token}+{secret_key}))
Да-да, часть подписи кодится дважды.
3.4. В ответ получаем JSON-список параметров, содержащий имя, ссылку на фото, день рождения и пр. Имя — utf8;
Полный список возвращаемых параметров функции users.getCurrentUser здесь. Описание API здесь. Но сразу предупреждаю, что автор его был болен рассеянным склерозом в последней стадии, поэтому о многих аспектах использования той или иной функции надо просто догадываться.

imageFacebook
1. Идем сюда и нажимаем «Создать новое приложение». В настройках в пункте App Domains вводим наш(и) домен(ы). Ставим галочку на «Website with Facebook Login» и вводим url нашего сайта. Записываем client_id (App ID) и secret_key (App Secret).imageНа вкладке «Auth Dialog» ставим галочку на «Authenticated Referrals» и тип «code» в «Auth Token Parameter». image
2. Кнопка на нашем сайте отправляет пользователя на:
https://www.facebook.com/dialog/oauth?client_id={client_id}&redirect_uri=mysite.com/fblogin&response_type=code
3.fblogin.
3.1. Анализируем строку на наличие code.
3.2. Выполняем GET запрос
GET https://graph.facebook.com/oauth/access_token?client_id={client_id}&redirect_uri=http://mysite.com/fblogin&client_secret={client_secret}&code={code}
3.3. Получаем в теле ответа список параметров в каноническом виде (param1=value1&param2=value2). Из полученного сейчас нам нужен только access_token, который мы вставляем в GET-запрос:
GET https://graph.facebook.com/me?access_token={access_token}
3.4. В ответ получаем JSON-список параметров, содержащий имя, ссылку на фото, день рождения и пр. Имя — NFC юникод (в виде \u0410\u0401\u0419)
Список функций API (и возвращаемых данных) здесь.

imageTwitter
1. Идем сюда и регаем новое приложение. Вводим имя, описание, наш сайт и урл скрпита-обработчика. imageНа странице настроек нажимаем кнопку «Create my access token».image

Дальше слов нет, сплошные эмоции. Горечь и боль переполняют меня. Ну зачем же они так??? Рекомендую для начала натравить на twitter какую-нибудь OAuth-библиотеку. И только, если ничего не получится (лично у меня не получилось подружить Net::OAuth с твиттером) вооружаемся терпением и лезем разбираться.

1. Здесь OAuth 1.0 и тут всё веселее. При нажатии пользователем кнопки «Зайти через Twitter» мы запускаем скрипт, который выполняет POST-запрос на
https://api.twitter.com/oauth/request_token
содержащий следующий заголовок:
Authorization:OAuth oauth_callback=«http%3A%2F%2Fmysite.com%2Ftwlogin», oauth_consumer_key="{consumer_key}", oauth_nonce="{nonce}", oauth_signature_method=«HMAC-SHA1», oauth_timestamp="{time}", oauth_signature="{sign}", oauth_version=«1.0»
Здесь oauth_callback — escape-uri функции-обработчика ответа от сервера;
consumer_key берется со страницы настроек приложения;
nonce — строка случайных base64 символов, в принципе, любой длины, хотя полагается 32байта, строка при каждом запросе должна быть новой, иначе сервер вернет ошибку;
time — unix-время сервера (обратите внимание, чтобы часовой пояс на сервере был выставлен правильно, сервер твиттера заворачивает как «просроченные» запросы, так и запросы «из будущего»);
а sign — это цифровая подпись по HMAC-SHA1 методу.
Время и nonce надо запомнить перед началом составления запроса — в подписи и в самом запросе эти параметры должны совпадать.
1.1. Как собирается подпись. Берутся все параметры и значения из строки запроса и его тела, escape-кодятся, сортируются по имени параметра и соединяются в одну строку через '&'. Базовая строка составляется так:
{ВИД_ЗАПРОСА}&{escape-uri запроса}&{escape-кодированная строка параметров}
Таким образом, строка параметров escape-енкодится два раза. Ладно, у нас тут частный случай, всё это можно забиыть и просто вставить нужные параметры вот в это:
str='POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3D{http%253A%252F%252Fmysite.com%252Ftwlogin}%26oauth_consumer_key%3D{consumer_key}%26oauth_nonce%3D{random base64 srting}%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D{time}%26oauth_version%3D1.0'
1.2. Дальше эта строка передается в функцию, вычисляющую hmac_sha1 подпись (гуглим, если не знаем, что это) с базой 64. Что-то типа такого:
str1=hmac_sha1(str,Consumer_secret+'&'+OAuth_token_secret,64).
У нас пока OAuth token secret-а нет, поэтому кодируем мы строкой, содержащей Consumer secret с добавленным в конце знаком '&'.Результат (если он бинарный) base_64 енкодим, а потом еще и escape-енкодим. Это у нас получилась подпись. Вставляем её в заголовок запроса и отправляем.
2. Получаем от сервера ответ, в случае успеха содержащий в теле ответа oauth_token=XXXXX. Редиректим пользователя на
https://api.twitter.com/oauth/authenticate?oauth_token=XXXXX
3. После успешной авторизации сервер вызывает наш скрипт twlogin, который:
3.1. Проверяет строку на наличие oauth_token и oauth_verifier (авторизация успешна)
3.2. Выполняет POST-запрос на
https://api.twitter.com/oauth/access_token
содержащий заголовок
Authorization:OAuth oauth_consumer_key="{consumer_key}", oauth_nonce="{random base64 string}", oauth_signature_method=«HMAC-SHA1», oauth_timestamp="{time}", oauth_signature="{sign}", oauth_token="{oauth_token}", oauth_version=«1.0»'
и, в теле запроса:
oauth_verifier={oauth_verifier}
oauth_token и oauth_verifier берутся из строки параметров, с которыми вызван наш скрипт, sign считается уже описанным методом из строки
str='POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Faccess_token&oauth_consumer_key%3D{consumer_key}%26oauth_nonce%3D{random base64 string}%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D{time}%26oauth_token%3D{oauth_token}%26oauth_verifier%3D{oauth_verifier}%26oauth_version%3D1.0';
3.3. В случае успеха приходит ответ, содержащий в каноническом виде список параметров. Выполняем GET-запрос
GET https://api.twitter.com/1/users/lookup.json?user_id={user_id}
с заголовком
Authorization:OAuth oauth_consumer_key="{consumer_key}", oauth_nonce="{random base64 string}", oauth_signature_method=«HMAC-SHA1», oauth_timestamp="{time}", oauth_signature="{sign}", oauth_token="{oauth_token}", oauth_version=«1.0»'
user_id и oauth_token берем из пришедшего списка, подпись считается на базе строки
str='GET&https%3A%2F%2Fapi.twitter.com%2F1%2Flookup.json&oauth_consumer_key%3D{consumer_key}%26oauth_nonce%3D{random base64 string}%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D{time}%26oauth_token%3D{oauth_token}%26oauth_version%3D1.0%26user_id%3D{user_id}'
и, теперь уже полученного в параметрах, oauth_token_secret:
str1=hmac_sha1(str,Consumer_secret+'&'+OAuth_token_secret,64)
3.4. В случае успеха нам приходит JSON-список параметров, содержащий имя, фото и пр. Полный список функций API и их описания здесь.

imageMail.ru (МойМир)
1. Идем сюда и регистрируем сайт. Вводим название, урл сайта и урл файла receiver.html, который можно скачать тут же. receiver.html — файл, инициализирующий JS API, и, в нашем случае он не нужен, но сервер МайлРу проверяет наличие этого файла по указанному адресу и не дает закончить регистрацию, пока этот receiver.html не окажется там, где полагается. На странице настроек получаем client_id (ID) и secret_key (секретный ключ).image2. Код кнопки должен быть вида:
<a href="https://connect.mail.ru/oauth/authorize?client_id={client_id}&response_type=code&redirect_uri=http%3A%2F%2Fmysite.com%2Fmmlogin">Войти через MailRu</a>
3. mmlogin
3.1. Анализируем строку на наличие code.
3.2. Выполняем POST запрос на:
https://connect.mail.ru/oauth/token
с параметрами в теле запроса:
client_id={client_id}&client_secret={secret_key}&grant_type=authorization_code&code={code}&redirect_uri=http://mysite.com/mmlogin
3.3. Получаем JSON список параметров, содержащий access_token. выполняем GET-запрос:
GET http://www.appsmail.ru/platform/api?method=users.getInfo&secure=1&app_id={client_id}&session_key={access_token}&sig={sign}
sign — md5-подпись
sign=hex_md5('app_id={client_id}method=users.getInfosecure=1session_key={access_token}{secret_key}')
в виде hex string.
3.4. В ответ получаем JSON-список параметров, содержащий имя, ссылку на фото, день рождения и пр. Имя — utf8;
Список функций API (и описания) здесь.

imageЯндекс
1. Идем сюда. Выбираем все права Яндекс.логин. Вводим параметры. image
Получаем client_id(Id приложения) и secret_key(Пароль приложения).image
2. Код кнопки должен быть вида:
<a href="https://oauth.yandex.ru/authorize?response_type=code&client_id={client_id}" title="Яндекс">Войти через Яндекс</a>
3. yalogin
3.1. Анализируем строку на наличие code.
3.2. Выполняем POST запрос на:
https://oauth.yandex.ru/token
с параметрами в теле запроса:
grant_type=authorization_code&code={code}&client_id={client_id}&client_secret={secret_key}
3.3. Получаем JSON список параметров, содержащий access_token. выполняем GET-запрос:
GET https://login.yandex.ru/info?format=json&oauth_token={access_token}
3.4. В ответ получаем JSON-список параметров, содержащий имя, email, день рождения. (Немного, но яндекс.логин больше не дает. Можно попробовать запросить дополнительные параметры с яндекс.мойкруг — предварительно дав на это права на странице наcтроек, но рассчитывать на развернутый ответ не стоит — количество пользователей почты яндекса и «Моего Круга» отличается в порядки.) Имя — NFC-юникод. Кстати, здесь используемая мной json-библиотека вдруг заглючила. Оказалось, в ответе от яндекса двоеточие от имени параметра отделено пробелом,
email : xxx@ttt.com
чего не наблюдалось в ответах от других сайтов. Тут явно ошибка библиотеки, RFC на JSON не запрещает лишние пробелы, но на всякий случай обращаю внимание — вдруг кто-то еще споткнется на этом.
Описание API yandex.login здесь.

imageGoogle
1. Идем сюда. Создаем новый проект. На вкладке API access нажимаем кнопку «Create an OAuth2 client ID».imageПолучаем client_id(Client ID) и secret_key(Client Secret).image
2. Код кнопки должен быть вида:
<a href="https://accounts.google.com/o/oauth2/auth?redirect_uri=http%3A%2F%2Fmysite.com%2Fgglogin&response_type=code&client_id={client_id}&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile" title="Войти через Google">Войти через Google</a>
3. gglogin
3.1. Анализируем строку на наличие code.
3.2. Выполняем POST запрос на:
https://accounts.google.com/o/oauth2/token
с параметрами в теле запроса:
code={code}&client_id={client_id}&client_secret={secret_key}&redirect_uri=http://mysite.com/gglogin&grant_type=authorization_code
и обязательно указываем тип запроса
Content-type:application/x-www-form-urlencoded
3.3. Получаем JSON список параметров, содержащий access_token. выполняем GET-запрос:
GET https://www.googleapis.com/oauth2/v1/userinfo?access_token={access_token}
3.4. В ответ получаем JSON-список запрошенных параметров.
Описание API работы с гугл-контактами здесь.

На этом пока все. Думаю, даже самые нелюдимые пользователи рунета имеют аккаунт хотя бы на одном из вышеупомянутых серверов.
Надеюсь, статья поможет тем, кто хочет сделать на своем сайте регистрацию по OAuth. Во всяком случае, попадись мне такая статья раньше, я бы сэкономил кучу времени и сил.
Я реализовывал это всё на perl, соответственно, если у кого возникнут вопросы по реализации OAuth на перле — могу дать свои рекомендации. По другим языкам — увы.
@skyranger
карма
15,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (179)

  • +2
    Таки OAuth или OAuth 2?
    • +3
      Оба.
      Большинство — OAuth 2, но на твиттере пока первый.
    • +3
      Первый ад и коровники. Второй нормальный и имеет RFC. Но есть одна маааленькая неувязочка. Информацию по пользователю все отдают как во что гаразд и стандарта нет. Так что приходится городить на каждого провайдера свою доставалку информации о клиенте.
      • 0
        А просто аутентификацию все одинаково реализуют? У всех пути одинаковы?
        • 0
          Да все реализуют одинаково. Пути не совсем одинаковые. Может меняться префикс к путям.
          • –1
            не все реализуют одинаково. например вк самоделка
            • 0
              Что именно в вк самоделка?
      • 0
        на второй — стандарта еще нет, есть довольно активно изменяющийся «черновик» стандарта.

        А на первый — да выглядит адско, но не требует SSL, есть фиксированный стандарт и рабочие проверенные библиотеки.
        Думаю что первый за счет своих плюшек проживет довольно долго, потому как второй Oauth идет по пути намеренного упрощения, что сужает сценарии использования т.к. SSL-must-have и предположение о том, что SSL не скомпроментирован (которое в общем наивно в свете всех новых техник...).
        • +1
          Второй адекватнее и проще чем oauth первой версии.
      • 0
        У нас более-менее получилось сделать универсально, в конфиге просто описываем ожидаемые поля возврата и делаем маппинг под свои. С email-ами проблема, иногда их приходится сочинять из имеющегося никнейма, но в нашем случае oauth-пользователь имеет ограниченный доступ, поэтому нормально.
  • 0
    Когда читал первые материалы по OAuth, то идея показалась очень интересной, но глядя на портяки кода для каждого сайта я каждый раз задумываюсь, то ли я неправильно понял в первый раз, то ли сайты как-то неправильно его реализуют, то ли ещё что, но почемуто нельзя, чтобы пользователь ввёл в простой инпут имя сайта, предоставляющего OAuth, а я должен предусмотреть на каких сайтах с OAuth мой посетитль может быть зарегистрирован. Причём, насколько я понимаю, догадаться о том какие сайт его предоставляют и как они пересекаются с моей аудиторией я должен сам.
    • 0
      Согласен, разная реализация крайне напрягает. Причём отличия настолько незначительны. В одном случае запрос надо делать через GET, в другом через POST, где-то redirect надо указывать в настройках приложения, а где-то передавать параметром. Плюс больше всего (лично меня) напрягают разные URL для запросов.

      Вот например Вконтакте (без параметров):
      oauth.vk.com/authorize (ссылка для авторизации и получения code)
      api.vk.com/oauth/access_token (получения токена)
      api.vk.com/method/getProfiles (метод для получения анкетной инфы)

      А вот Facebook:
      www.facebook.com/dialog/oauth
      graph.facebook.com/oauth/access_token
      graph.facebook.com/me

      При этом передаваемые параметры тоже отличаются. К чем я это всё… а то что действительно стандарт вроде есть, а реализация различается настолько, что к каждому новому провайдеру нужен свой подход и это печально.
      Жду не дождусь OAuth 3.0.
      • +1
        А зачем вы так наивно смешиваете авторизацию и обращения к Апи? Последние урлы в обоих блоках это уже работа с АПИ.

        OAuth 2.0 довольно простая и понятная штука, только осваивать ее надо не по экспериментам а почитав драфт страндарта ( который кстати еще не устаканился). тогда и вопросов не будет — надо или не надо передавать в урле или регистрировать приложение. Там все просто — есть то, что приложение должно делать — все «имена и фамилии» там совпадают, а есть то, что может делать (или может не делать). И тут уже на усмотрение реализующего. Вас же не удивляет что на разных сайтах страницы называются по-разному, так почему же претензии к адресам\endpoint'ам?

        Это касается и редиректов\урлей — в реальности нужно минимум 2, (максимум 3 адреса еще один удобен для получения неподписанного токена, хотя часто это делают прям в момент выдачи авторизационного кода). А все параметры которые нужно передавать — зафиксированы в драфте стандарта. даже имена совпадают…

        • 0
          Поймите меня правильно, меня действительно напрягает то, что протокол реализован у разных провайдеров немного по-разному. И в основном всё это было риторически…
          • 0
            Протокол описывается стандартом. Вернее пока еще draft 27 (ого, недавно был 25) — tools.ietf.org/html/draft-ietf-oauth-v2-27

            Никто его не реализует по-своему. Ну есть только версии одного драфта — кто-то реализовывал версию 22, кто-то 14, но там детали обычному пользователю не сильно заметны.

            Endpoint'ы для запроса токена у всех разные (хотя суть их — как описывает стандарт). И у нас тоже свои имена endpoint'ов, это нормально, 2 строки в конфиге для каждого провайдера — не много работы.
            • 0
              endpointы разные, тела ответов разные не многовато ли?
              • 0
                нет, не многовато. к Oauth имеют отношения только endpoint'ы. Тела ответов — это работа с API каждого провадейра.
                • 0
                  чтож а как насчет разных параметров(у ya.ru статичный redirect_uri, у вк redirect_uri для получения токена не нужен)
                  а это вообще зачем?)
                  grant_type=authorization_code
          • 0
            На самом деле в .NET есть прекрасная библиотека DotNetOpenAuth, которая, при желании, спрячет от вас все детали реализации. Вот только там абстракция довольно глубокая (чуть ли не отвязка от http протокола), а сам протокол OAuth довольно простой, чтобы его можно было реализовать и руками. Прочтите один-два раза стандарт и все встанет на свои места.

            PS Хотя я допускаю что отдельные деятели могли накосячить в своей реализации, или схалтурничать
    • +2
      Во-первых, по отношению к пользователю намного дружелюбнее будет предоставлять на выбор несколько заготовленных вариантов.

      Во-вторых, OAuth изначально задумывался как протокол авторизации, что подразумевает априорную информацию не только о конкретных OAuth-powered сайтах, но и о ресурсах/действиях на них, требующих авторизации.
      Уже когда OAuth начали использовать и для простой аутентификации, стандарт стал пытаться поддерживать оба workflow.
      • +2
        стандарт не стал пытаться поддерживать оба workflow, он как был авторизацией так и остался. Просто сайты предоставили некоторые отдельные апи не для совершения действий от имени пользователя а для получения информации об этом пользователе. Т.к. информация у них «надежная» (т.е. вы доверяете тому, что ФБ вас не обманет, отдавая email пользователя), то вы можете использовать ее для того, чтобы аутентифицировать клиента у себя на сайте.

        Это никак не противоречит единственному предназначению протокола OAuth 2.0 — авторизации.
        :)
    • +1
      Разная реализация только у одной вещи под названием взять данные о пользователе. И эта часть вообще не описана в OAuth. То что описано в draft работает если сайт заявляет совместимость с oAuth 2.0
      • 0
        Ну вот смотрю что у разных сайтов разные URL, различающиеся не только доменом, но и путями. Беглый просмотр стандарта тоже не показал, что пути им специфицируются. То есть для реализации аутентификации пользователя на произвольном сервере, мне нужно сделать поле для ввода полного URL а не домена. И хорошо если хватит одного поля, а не несколько URL вводить нужно будет пользователю.
        • 0
          Ну вот смотрю что у разных сайтов разные URL, различающиеся не только доменом, но и путями.

          Внимательно посмотрите и сравните со стандартом. Увидите, что на самом деле пути специфицированы.

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

          Вы не сможете сделать реализацию аутентификации пользователя на произвольном домене. Потому что вам требуется иметь уникальный идентификатор и секретный хеш от этого сервера. А если у вас они есть, то и url все необходимые у вас есть.
        • +1
          Поле для ввода URL OAuth от пользователя? да вы герой, ну или кандидат на новости о взломе…

          Oauth не предполагает доверие всем подряд ( в отличии от OpenId) — вы, как владелец сервиса, сами определяете, каким внешним OAuth сервисам будете доверять.
  • +3
    Я как раз не люблю OAuth. Не люблю связывать свой эмейл (в случае с гмейлом) или профиль социалки (контактик) с каким-то левым сайтом…

    А фейсбука (90% зарубежных OAuth авторизаций требуют его и чуть ли не только его) у меня вообще нету.
    • +11
      Это не говоря о том, что OAuth любит запрашивать всякую инфу. И нельзя снять галочку с «предоставить эту инфу» — можно либо полностью согласиться, либо идти лесом и остаться незарегистрированным гостем.
      • 0
        в фэйсбуке было можно некоторое время. Сейчас — давно не пользовался. можно было предоставить только Core needs ( без которых нельзя), а остальное опционно отозвать. Но это авторская реализация, стандарт такому не обязывает (хотя дает возможности сделать)

        А если вы слабо доверяете приложению — я бы туда даже емейл не вбивал, не говоря о том, что авторизовывать его на ФБ…
    • –2
      Никто вам не запрещает в любой момент отключить доступ к вашему аккаунту, это делается в настройках профиля.
      • 0
        Этак уже поздно будет. Оно конечно лучше, чем никогда, но все же…
  • –1
    Может быть просто loginza?
    • +1
      или ulogin
    • +4
      Loginza и прочие подобные сервисы проще, но!
      — нет возможностей для кастомизации
      — по отзывам часто глючит
      — вы не застрахованы от того, что в какой-то момент сервис просто «упадёт»
      • +1
        За месяц более 17М входов через ulogin, я подозреваю что они заботятся о том, чтобы у них не падали сервера.
        Ходят слухи, что можно кастомизировать кнопки, обратившись в техподдержку.
        • 0
          Тогда возражу тем, что всё же своя форма авторизации даёт тебе какую-никакую, но индивидуальность.
          • 0
            Если цель оправдывает средства, то почему бы и нет ;)
            • 0
              В данном случае средства (для специалиста в этой области) — это один лишь вечер. А профита от этого вечера довольно много.
      • 0
        у Ulogin зато есть свои плюшки, падает/ломается все…
    • +6
      нет, для гадов, требующих регистрацию — только bugmenot
      • 0
        Если надо быстро зайти на закрытый форум, что-то прочитать\качнуть, то да. А если я хочу постоянно пользоваться сервисом, то бегать на bugmenot станет лениво.
    • 0
      Об этом написано в тексте «Почему OAuth, а не виджет».
      Меня не устраивают функционал, дизайн и надежность виджета
    • +1
      омг зачем, oauth2 и так простой
    • 0
      Использую в своем проекте ее. Но из-за невозможности настроить ее, часть пользователей проходят мимо. Жалоба, например, логинза хочет иметь доступ к контактам из гмеила. Захрен ее это надо не ясно. Со стимом рабоатет коряво.
  • +3
    Спрошу здесь, оффтопиком:
    Интересно почитать про то как написать сервер OAuth?
    • +1
      могу нарватся на звание Капитана, но берете спецификацию версии, которую хотите реализировать и делаете. Есть сущности тоукена, рефреш тоукена, кода авторизации. Жонглируйте в своем приложении как хотите. В некоторой мере использование 3rd parties библиотек скорее создает ограничения, чем преимущество, так как имплементация что на сервере что на клиенте очень тривиальная.
      • +1
        Правильный ответ. ППКС.

        Минусуют не разбирающиеся зануды
    • +1
      Я пользую github.com/honza/oauth-service =)
      Есть еще на основе всяких REST-фрэймворков для django типа tastypie/piston.
      Вообще ведь не очень сложно написать используя что-то типа django'вской django-tastypie — я думаю в каждом языке/фреймворке найдется куча аналогов.
    • +1
      Очень просто. Берете стандарт указанный выше и пишите по нему серверную часть. Никакой ракетной науки там нет. Реализация именно сервера займет максимум страницу кода. Если остальные свистелки добавлять типа админки, регистрации сайтов и т.п. то немного побольше.
    • 0
      провайдер? мне — да, интересно. смотря какой язык
    • 0
      Можно написать свой, например, на Rails для этого есть Doorkeeper:
      doorkeeper
      wiki/Example-Applications
      wiki
  • +8
    Я не люблю зависеть от всяких loginza или ulogin
    Предпочитаю сам к сайту прикрутить django-social-auth, где представлены следующие бэкенды для авторизации:
    OpenId, OAuth, Twitter, Facebook, Orkut, Google OAuth, Google OAuth2, LinkedIn, GitHub, Bitbucket, Dropbox, Flickr, BrowserID, Instagram, Vkontakte, MSN Live Connect, Skyrock, Yahoo OAuth, Evernote OAuth, Yandex OAuth and OpenID, Mail.ru OAuth, Odnoklassniki.ru а еще отдельно добавляю last.fm, tumblr.com бэкенды.
    • 0
      Там еще foursquare есть и еще какие-то. Ну и свой бэкенд не сложно написать если у сайта есть Oauth API или OpenID. С loginza/ulogin своего бэкенда не подключишь)
    • 0
      Кстати практически никакой сервис типа loginza/ulogin не поддерживает Mozilla'вский BrowserID.
      • 0
        Какой процент пользователей использует BrowserID? Пока это только фишки, которые, возможно, стартанут в будущем… Вероятно, если BrowserID станет популярен, то loginza/ulogin их добавят.
        • –1
          Ну некоторые гики пользуют и то мало среди них русских. Кстати, поддержка BrowserID добавлена в django-social-auth по моей наводке.
          Естественно по статистике этих самых ulogin/loginza окажется что доля никакая — потомучто никто не поддерживает.
          Я вот к примеру не хочу писать какие-либо комменты или регистрироваться от лица своих аккаунтов на твиттере или фейсбуке. Мне удобнее BrowserID.
    • 0
      можешь пожалуйста дать пару django сайтов где этот плагин используется?
  • +2
    Всё замечательно, но один момент — чтобы мне, например сделать авторизацию через OAuth на том же Вконтакте или Фейсбуке — надо там зарегистрироваться…
    • +2
      Да, надо. Если вдуматься, это логично. С чего бы тому же ВКонтакту или Фейсбуку давать доступ практически ко всем своим механизмам какому-то неизвестному сайту? Один из немаленьких плюсов авторизации по OAuth это как раз доступ к API сервера. Так зарегистрированный пользователь оставит на сайте в лучшем случае свой пол, город и возраст. А обычно и вовсе ограничится требуемым минимумом. А с зашедшего со ВКонтакта — столько можно инфы натащить, что ой :)
      Не то, чтобы эта инфа была нужна, но наличие возможности её получить — не помешает.
      • 0
        Ну я как вебмастер, например, хочу дать пользователям возможность зайти через ВКонтакт. Но сам не согласен с его условиями регистрации, что делать?
        • 0
          Использовать vkontakteid.ru, например. Там OpenID.
          • 0
            Вы так минусуете, как будто есть другие варианты :)
          • +1
            OpenID хорош до тех пор пока вы не наткнулись на самописного опенид провайдера который отдает трэш по желанию автора. Поддерживать openId только от сайта Х — странно, т.к. провайдеров очень много, обычно поддерживают «любой openId»
            • +1
              Захотят подсунуть треш — кто мешает зарегать под это дело новый email на яндексе или гугле?

              Как по мне, OpenID хорош тем, что, в отличие от OAuth, он таки предназначен именно для аутентификации. А то, что описывает автор в статье — это типичный misuse, использование не по назначению. Отсюда и геморрой с индивидуальным подключением каждого сайта, что для аутентификации явно перебор.

              Для сервиса OpenID удобен тем, что не требуется реализовывать особую поддержку для разных сайтов. Пользователь ввёл свой url — и его проверка выполняется одинаково, вне зависимости от того, на какой сайт он ведёт. При желании, можно реализовать упрощённый вход для некоторых крупных OpenID провайдеров спрашивая имя юзера, а не url, но это мелочь ничего принципиально не усложняющая.

              Для пользователей OpenID удобен тем, что они могут контролировать какая информация к нему привязана, включая полное отсутствие этой информации. Кроме того, это позволяет не давать левым сервисам доступ (даже ограниченный) к своим аккаунтам в других сервисах. И других плюсов тоже куча, хотя, да, большая их часть нафиг не нужна людям, которые не видят ничего плохого в выкладывании моря информации о себе в сеть, связывания вместе информации о себе находящейся на разных сайтах, и предоставления доступа к этой информации кому попало.
              • +1
                Знаете, зарегать много аккаунтов на гугле — куда сложнее чем написать свой сервис openID который каждый раз будет отдавать псевдо-правдивые данные. Все же тут направление — обойти запрет массовой регистрации. Крупные сервисы с этим стараются бороться.

                OpenId, со всеми их namespace и расширениями — та еще «бядаа» к тому же там вроде есть фундаментальные проблемы (сейчас сходу не вспомню) и кроме «быстрой регистрации» оно ни на что особо не годен.
                И да, вы не можете доверять «любому» OpenID сервису для аутентификации ( или вам аутентифицировать надо только по полному OpenID имени, т.е. логин будет не удобный centur а centur.myopenid.com, т.е. юзернейм-на-сервисе. Потому что на другом сервисе под тем же ником может быть другой пользователь.

                И да, никто не мешает для своего openid сервера на centur.myhackenid.com отдавать чужой email. Если активно используете email — прийдется валидировать владельца все равно, а в случае с Oauth — вы доверяете конкретному сервису и даже можете получить больше данных чем из openid, т.к. сервис что-то делает обязательным, а openid предлагает определить набор предоставляемых данных самому пользователю

                Да, с OpenId тоже можно доверять 1-2 сервакам, но тогда вся его openness исчезает.
                • –1
                  Вы смешиваете в одну кучу разные задачи.

                  OpenID решает одну простую проблему: избавляет юзера от необходимости придумывать на каждом сайте логин/пароль и вводить своё имя, ник и email. Что увеличивает вероятность того, что юзер таки зарегистрируется на сайте, а не плюнет и закроет страничку увидев очередную форму регистрации. Причём OpenID никак не уменьшает безопасность или приватность если юзер воспользуется возможностью поднять OpenID-провайдер на своём сайте.

                  Это не избавляет сайт от необходимости проверять email юзера (впрочем, юзеру кликнуть reply-send или по ссылке в письме обычно не очень трудно) или использовать капчу для защиты от массовых регистраций.

                  Что касается «неудобного логина centur.myopenid.com» то это не так — OpenID предоставляет возможность получить ник юзера, который по сути и есть короткий предпочитаемый логин.

                  Что касается попытки избежать ввода капчи и проверки email при работе с доверенными сервисами — никто не мешает точно так же доверять тем же самым сервисам при работе с ними по OpenID — если вы доверяете гуглу по OAuth, почему вы считаете, что по OpenID он вам пришлёт какие-то другие данные, которым нельзя точно так же доверять? При таком подходе распознав «доверенного» OpenID-провайдера вы просто пропускаете запрос капчи и валидацию email, только и всего.

                  Если же вам категорически необходимо полностью отказаться от своей собственной формы регистрации (оставив только вход через чужие сервисы), вы почему-то не хотите реализовывать проверку капчи и email-а, и вам жизненно необходимо получить кучу дополнительной информации о пользователе (вроде страны/города) — тогда да, ничего кроме как использовать не по назначению OAuth и морочиться описанным в статье геморроем вам не остаётся. Просто понимайте, почему и для чего вы это делаете — что этот подход не облегчает жизнь пользователю, более того он активно нарушает privacy пользователя, а в плане реализации он просто заменяет одни задачи (реализацию капчи и проверки email) на другие (описанные в статье).
                  • +1
                    Да, да, и еще тысячу раз «да». Всё верно.
                    Вот только подавляющему большинству пользователей наплевать на свою privacy, но, в то же время, очень тяжко нажать хотя бы одну лишнюю клавишу.
                    Мне (как подавленному меньшинству) это тоже очень грустно, но (как админ нескольких ресурсов) я не имею права проигнорировать эту тенденцию.
                    • 0
                      Ну что тут скажешь. Лично мне будет крайне печально, если реализуя поддержку OAuth вы одновременно отрежете поддержку OpenID. Ибо аккаунтов в соц. сетях и твиттере у меня нет, а свой гугловский email я светить при регистрации на сайтах не планирую.
                  • 0
                    Лично я — не смешиваю, я их очень хорошо отличаю.

                    OpenId — это быстрая регистрация. Проблема «быстрой регистрации» в том, что ее очень любят боты.

                    OAuth 1.0 и 2.0 — это способ авторизации стороннего приложения для доступа к ресурсам от имени пользователя. Для аутентификации это используется так, что спрашивается емейл пользователя и этому ответу доверяем.

                    Касательно «кликнуть по ссылке» — это не так, пользователи обычно ленивы и не ходят в почту, кривая почта может попасть в спам или вообще быть убитой на сервере, не дойдя до ящика пользователя. Все это не увеличивает количество пользователей с проверенными email.

                    В случае с доверием ЛЮБОМУ OpenID провайдеру (доверять 1-2-3 и не доверять другим — работает, но выглядит дико) — есть простая проблема. Я напишу свой openId сервер таким образом, что он будет ВСЕГДА генерить рэндомные комбинации юзернейма, email на моем домене ( или на mailinator.com) и будет сам активировать присланные письма. И добро пожаловать в мир миллиона халявно зарегистрированных аккаунтов на вашем сервере.

                    Если же мы доверяем «только нескольким» серверам Oauth\OpenID — то мы предполагаем что там и email уже валидный, можно самому не валидировать (если там не валидный- это значит большие проблемы), и что сами сервисы умеют хорошо защищаться от массовой регистрации аккаунтов у них самих, ну хотя бы получше чем вы сами.

                    Но даже в этом случае (это касательно «удобного логина») никто не защитит вас от сценария, когда вы зареганы на OpenID-Provider-1 и желаемый login у вас user1 а почта user1@gmail.com, а я зареган на OpenID-Provider-2, а вот никнейм (суть логин) я вписал тоже user1. А еще если мой провайдер кривой и НЕ проверяет почту на владение (т.е. при вводе почты вам нужно перейти по ссылке ) или я как-то смог подтвердить почту user1@gmail.com, то я легко зайду под вашим аккунтом в сайт, который доверяет обоим провайдерам.

                    Поэтому мечты об удобном предпочитаемом логине user1, а не user1.OpenId-Provider-1 идут далеко и надолго. Это вроде очевидно.

                    В остальном же про капчу\емейл и т.д, в общем возражений нету и я говорил примерно то же самое что и вы. Для меня OAuth технически удобней OpenID, даже если он используется не по назначению.

                    А так — почта, только почта может честно, уникально и удобно идентифицировать юзера ;)
                    • +1
                      Все это не увеличивает количество пользователей с проверенными email.
                      От жеж дался Вам этот проверенный email! Я, как и все, зареган на сотнях сайтов. И при этом практически никто из них никогда не присылает мне никаких писем. Ибо для их функциональности это не требуется. Вопрос1: нафига им всем мой email? Вопрос2: нафига мне им давать свой настоящий, регулярно читаемый email?

                      Регистрация на сайте нужна для того, чтобы отличать одного пользователя от другого. Для этого нужен логин+пароль либо OpenID, email для этого не нужен.

                      Сайтам, которые требуют email, но письма от которых мне не нужны (т.е. практически всем) я как правило подсовываю специально под это дело открытый ящик на яндексе. И захожу в него исключительно тогда, когда ожидаю получить письмо проверяющее мой email. Ну и радости вам от такого проверенного email? (При необходимости, точно так же заводится фейковый аккаунт в каком-нить фейсбуке, на тот же левый email, и используется для регистрации/логина на сайтах.)

                      А в тех случаях, когда пользователь заинтересован в получении писем от вашего сайта — он сам побеспокоится указать настоящий email и без проблем верифицирует его.

                      В общем, получается так, что единственная реальная причина по которой абсолютное большинство сайтов может так сильно хотеть узнать мой активно используемый email — спам и реклама. А регистрация на сайте — это просто удобный повод этот email получить.
                      • 0
                        неа, для того чтобы вы могли отличать одного пользователя от другого — вам не нужна регистрация. Можно тупо взять юзерагента+ плагины с версиями и получится очень уникальная строка. Где-то в юса-вузе это уже показали на практике.

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

                        Если приложение не хочет или не может хранить инфу для проверяемого секрета, оно может перевалить эту обязанность другому сайту ( это некоторая вольная интерпретация). Например если наш сайт Х доверяет тому, как гугл хранит и защищает пароли пользователей, то мы, делая вход через гугл, декларируем следующее: «Я доверяю гуглу, поэтому я не буду сам проверять ваш пароль, а пусть гугл проверит ваш пароль на нем, а мне скажет ваш логин. Вот как он скжет, так я вас и залогиню». Все, вы можете не хранить хэши паролей вообще, а просто собрать набор сайтов, которым вы доверяете и жить на этом «доверии».

                        Если один из таких доверенных сайтов фэйлит — у вас проблемы, т.к. в чужой акк на вашем сервере можно зайти обманув доверенный сервер.

                        OpenId изначально не предполагает такой уровень доверия, OpenId говорит как бы — «Сайт, вот тебе строка моего логина на сайте, по стандартному протоколу ты можешь получить обо мне всю информацию что я завел».
                        Но это никак не подтвердит что вы — именно тот человек, который это заводил. Поэтому для быстрой регистрации опенид — допустим, а вот для дальнейшего регулярного входа на сайт — должно быть то же самое «доверие» к провайдеру. А провайдер может поручиться только за записи, которые явно с ним связаны, поэтому сайт должен держать связь логин+провайдер, что на самом деле ружит идею опенид почти полностью, потому как предполагалось что сайты будут доверять ЛЮБОМУ опенид провайдеру.

                        А все-таки насчет масс регистрации — одно дело когда сайт — это форум, ну пришли боты, потроллили и все такое. А другое дело — когда это некий сервис предоставляющий демо-услугу, а за больший объем хотящий денег. Вто там массовая регистрация позволит получить услугу в большем объеме (маленькими демо-кусочками) и возможно нанесет финансовый ущерб сайту.

                        Все в итоге зависит от того, что именно вы предоставляете и насколько важна для вас регистрация.
                        • 0
                          «Сайт, вот тебе строка моего логина на сайте, по стандартному протоколу ты можешь получить обо мне всю информацию что я завел».
                          Но это никак не подтвердит что вы — именно тот человек, который это заводил.
                          Это как?! Во-первых, по OpenID вам никто никаких логинов не даёт. Вам дают url. Во-вторых, суть OpenID — это возможность проверить, что регистрирующийся или логинящийся человек действительно «контролирует» эту url.

                          И хотя для некоторых сайтов возможно автоматически определить url узнав имя аккаунта на этих сайтах, суть от этого не меняется — спросив у юзера имя аккаунта вместо url вы просто немного улучшили юзабитили, но всё-равно вы первым делом вычисляете по аккаунту url, и проверяете по OpenID именно этот url.

                          Откуда Вы вообще взяли эту идею про связь «логин+провайдер» и каким боком тут OpenID?
                          • 0
                            Да, торопился ( выезжал на работу) и невнимательно выразился. Вы правы, OpenId действительно про доказательство контроля конкретного url, и «логин» там может только улучшить юзабилити, все равно будет сформирован ожидаемый урл. Все так.

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

                            Но вот OpenId протокол не подтверждает, что пользователь, владеющий урлом, действительно владеет теми данными, которые он ввел. И создавать на основе этого аккаунт без проверки «владения» заявленным email не обойтись. Это необходимо в «общем» случае.

                            Если использовать только проверенные сервера-провайдеры openId (частный случай), которые сами требуют валидации email, тогда все ок.
                            Но такой подход противоречит самой идее OpenID — когда ты можешь войти на сайт, используя любой, даже собственный OpenId провайдер на домашнем сервере
                        • 0
                          Да, и к чему Вы продолжаете постоянно упоминать массовую регистрацию? Использование OpenID не мешает параллельно защищаться от массовой регистрации, это уже много раз упоминалось. Если лень прикрутить капчу — это основание для отказа от OpenID — дело Ваше, но надо отдавать себе отчёт, что это не с OpenID что-то не так, а просто Вам лениво.
                          • 0
                            Да не в капче дело, и не в лени. Я пытаюсь сказать, что openId — это только способ быстрой РЕГИСТРАЦИИ, после которой надо еще отдельно аутентифицировать пользователя.
                            Максимум, что можно использовать для секрета аутентификации — это сам url, владение которым пользователь заявил. А вот делать на основе этого «владения» предположения, что он владеет и email, который был возвращен провайдером — нельзя, email надо проверять отдельно ( или использовать только тех провайдеров, которые делают эту проверку за вас, т.е. ограниченный список)

                            Пустить на сайт означает аутентифицировать, а не зарегистрировать. Я могу зарегать аккаунт на ваш email, но без доступа к вашему ящику, я не смогу провалидировать мое «заявление» о том «я — владелец ящика». Эта проверка нужна для определенных сценариев

                            А OAuth в текущем виде и в сценарии его общепринятого «нетрадиционного использования» сможет именно подтвердить АУТЕНТИФИКАЦИЮ пользователя.

                            В этом вся разница, которую я хотел донести.
                            • 0
                              OpenID это не способ регистрации! Это способ именно аутентификации пользователя, а что вы будете с этим делать дальше — регистрировать аккаунт или логинить в уже существующий — дело ваше.

                              OpenID позволяет аутентифицировать пользователя. Пользователя, а не его email. Вы постоянно говорите «пользователь», а подразумеваете при этом «проверенный email». А это разные понятия.

                              Изначально, на заре веба, email при регистрации на большинстве сайтов требовался для фичи «восстановление пароля». С OpenID нужды в этой фиче больше нет. Возникает вопрос: нафига большинству веб-проектов email пользователя? Отправлять пользователю разные полезные письма? Ну, если письма действительно полезные — пользователь сам побеспокоится о том, чтобы указать свой реальный email. И какая вам разница, пользователь указал настоящий email или левый, свой или чужой? На случай указания чужого email-а, просто добавляйте в письма ссылку «я не регистрировался на вашем сайте, кто-то использовал мой email» — будет вам валидация наоборот.
                              • 0
                                ОКей… С точки зрения сферического коня — вы правы OpenId можно использовать для аутентификации и для регистрации. Вопрос — нужно ли?

                                Есть несколько «неудобств» OpenId, с которыми «обычно» не соглашаются интерфейс-дизайнеры:

                                1. Для аутентификации — надо ввести руками строку\урль, OAuth позволяет сделать то же самое действие одним кликом, или даже прозрачно на яваскрипте (см. StackOverflow например).

                                2. Для регистрации — надо провалидировать email (если он нужен, а в сервисах он обычно нужен, домашние странички васи даже регистрации не должны требовать ;) ).
                                Платформа предлагающая OAuth в этом случае «обычно» берет на себя проверку все того же пресловутого email (да да, кроме твиттера, которому даже переход на OAuth 2.0 не поможет), т.к. сервис-сайт все равно регистрируется для доступа к «платформе», то он может выбрать те, что предоставляют проверенные данные.

                                Итак п.1 неудобен т.к. батхертит пользователей — надо вбить урл вместо клика на кнопке «войти»

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

                                Про полезность писем — вопрос другой. В большинстве случаев если сервис спрашивает, значит считает что письма полезные ( и попробуй переубеди его ;) ), т.е. email чаще нужен, чем нет.

                                Можно избежать п.2 и пускать только пользователей определенного набора провайдеров OpenID, которые сами требуют валидацию нужных вам данных.
                                Это, во-первых, приводит к ситуации, когда приходят в саппорт юзеры и начинают ныть — «А почему вы пускаете OpenA и не пускаете OpenB, это дискриминация» или «А почему вы не пускаете всех подряд, вот у меня дома на роутере стоит свой OpenId провайдер, я хочу чтобы ваш сервис верил тому, что он „рассказывает“.
                                Во-вторых — сводит удобство OpenID, как универсального и провайдеро-независимого решения, на нет. т.к. появляется зависимость от провайдера.

                                В чем преимущество OAuth — есть удобство общего назначения, в виде доступа к API конкретной платформы: получить данные о пользователе, на стене написать, календарик попросить и что-нить полезное показать, подсказать друзей которые уже на сервисе и все такое.

                                Есть частное удобство для пользователя — он чаще уже залогинен в сервис платформы (ибо он часто пользуется соцсетью, куда чаще чем своим „провайдером“, которые часто ничего кроме „провайдера OpenId“ и не предоставляют). И в этом случае — ему надо сделать максимум 2 клика ( кнопка войти и кнопка разрешить доступ приложению) чтобы оказаться на сайте. А в идеале (повторный заход) — вообще в один клик. И все, остальное делают сервисы, автоматически, ну 1-2 редиректа в фоне пролетят, юзер и не заметит.

                                И вот именно этот сценарий, который удобен как юзеру, так и сайту (заботящемуся о легком входе к себе, но требующему некоторой проверенной информации для работы) побеждает.

                                А OpenId c его идеологией и свистоплясками слишком неудобен для всех сторон:
                                1. Юзеру надо вводить урль ( что обычно длинее логина, а если вводить логин — надо выбрать правильного своего провайдера).
                                2. Сервису надо в любом случае проверить данные о пользователе от провайдера, или довериться конкретному провайдеру (что приведет к ограничениям описанным ранее и аннулирует преимущества OpenId)

                                Ну и кому, кроме убежденных гиков, нужна эта „морская свинка“ от мира аутентификации и регистрации под названием OpenID 2.0?

                                Юзерам лень что-то делать, а сервисы хотят переложить не нужную им работу на других (валидация данных).

                                Все, силы разума в очередной раз победили вселенское сферическое добро.
                                • 0
                                  В общем и целом — да, всё так. Но есть мелкие нюансы. :)

                                  Во-первых, что касается входа одним кликом без ввода url. Я довольно часто пользуюсь OpenID, но не помню, когда последний раз ручками вводил url — обычно я успеваю нажать только первую букву, и браузер сам предлагает вписать нужную url. Так что на самом деле разница между одним кликом, и одной буквой и парой кликов не так велика.

                                  Во-вторых, что касается проверки email — при использовании OAuth пользователи десятка крупных сервисов могут не валидировать свой email, а всех остальных пользователей вы фактически (предполагая, что своей регистрации у вас нет) вынуждаете сначала открыть аккаунт на одном из этих крупных сервисов а потом снова зайти на ваш сайт. При использовании OpenID (предполагая что эти же крупные сервисы поддерживают и OAuth и OpenID) пользователи этих сервисов точно так же избавлены от необходимости верифицировать свой email (т.к. конкрентно этим провайдерам вы доверяете), а остальные спокойно регистрируются используя любые OpenID провайдеры но вынуждены верифицировать свой email. Таким образом разница в юзабилити в данном случае как раз в пользу OpenID — ведь верифицировать email намного проще открытия аккаунта в крупных соц. сетях (в процессе чего всё-равно придётся верифицировать свой email).

                                  Таким образом, разница в юзабилити между OpenID и OAuth не так уж и существенна. А если сайт предоставляет возможность входа и по OpenID и по OAuth то юзабилити вообще никак не страдает.

                                  Но даже если допустить, что преимущества OAuth перед OpenID в плане юзабилити процесса логина бесспорны и очень важны — это плюс, но нельзя ведь учитывать одни плюсы, игнорируя при этом минусы, верно? А минусов у OAuth хватает. Безусловно, все эти минусы магическим образом становятся плюсами если вашему сайту действительно необходимо работать с функциональностью соц. сети — писать на стене и т.п., но мы ведь обсуждаем использование OAuth не для того, для чего оно изначально было предназначено, а исключительно как замену аутентификации и не более того.

                                  С моей точки зрения, предоставление сайтам лишней информации о себе (включая информирование сайта соц. сети на какие другие сайты я логинюсь используя их OAuth) — это громадное зло, которое ещё выйдет боком этому миру. Но на некоторые грабли просто необходимо сначала наступить, ибо пока жаренный петух в жопу не клюнет голова работать не начнёт. Использование OpenID, по крайней мере, оставляет шанс избежать сообщения лишней информации о себе третьей стороне подняв свой провайдер OpenID. OAuth такого шанса не даёт — разве что регистрировать кучу отдельных fake аккаунтов в соц. сети исключительно для логина на разные сайты.

                                  Резюмируя наше длительное общение. Хотите иметь описанный в статье геморрой ради того, чтобы сэкономить юзеру ввод одной буквы и один клик при регистрации/логине — дело Ваше, вреда от этого никакого нет. А вот если Вы сделаете вход только по OAuth, без OpenID и/или отдельной регистрации — это уже будет однозначное зло. Разумеется, это касается только сайтов, где OAuth используется не по прямому назначению, а исключительно для аутентификации.
                                  • 0
                                    ;) Если говорить о дополнительных средствах типа подсказки от браузера — то тогда недалеко и до LastPass — автоввод регистрационных данных, генерация и запоминание паролей и все такое. Но это по сути сторонние фичи. в случае Raw — OpenID проигрывает OAuth по юзабилити. Даже мне не нравится вводить первую букву, т.к. серфинг все же идет при помощи мыши, а не клавы ;)
                                    Написание на стены и все такое — это необязательно надо пользовать, но комфортно и удобно получить дополнительные фичи за 1 проход…

                                    Базовый запрос в OpenId может быть тоже строгий и сайт может попросить от провайдера максимум информации о юзере — кладем все поля в required и пользователь не получит доступа, пока все не расскажет.

                                    Протокол никак не меняет возможность сайта запросить максимум лишней инфы не пускать пока не получит.

                                    Oauth чаще всего сообщает базовую инфу о пользователе которая доступна публично (facebook) либо пользователь явно видит — сайт хочет получить доступ к email (google пишет).

                                    Также уже сейчас некоторые реализации OAuth позволяют подменять прям на лету важную инфу ( анонимный email в facebook или мультиаккаунт в Google). А для OpenId это вряд ли будут делать.

                                    Сайты без old-style регистрации — конечно же зло, а вот просто без OpenID — не вижу проблем. У нас только Old-style + Facebook + Google, и все довольно хорошо.

                                    А насчет заставлять регистрироваться на сайте соцсети — ну с 99% вероятностью (высосано из пальца, но фактически примерно так и есть) у всех моих знакомых есть аккаунт в соцсети, но что такое OpenId и как им правильно пользоваться — от силы знают 5%. А уж аккаунты в OpenId провайдерах (кроме ЖЖ, потому что это сначала соцсеть, а потом уже провайдер) — если у 3х людей найду — буду удивлен.

                                    А гемморой из статьи получать не нужно, надо читать спеки и реализовывать, там не сложно. А главное — всегда понимать, что именно ты делаешь в коде и для чего.

                                    Спасибо за приятное и пламенное общение ;)
                            • 0
                              Этот комментарий — странный запутаный гон, написанный в пробке на мкаде.
                    • 0
                      И добро пожаловать в мир миллиона халявно зарегистрированных аккаунтов на вашем сервере.
                      Как я уже на это отвечал выше — используй капчу, Люк! Проверяй кол-во регистраций с одного IP. Если на сайте есть форма обычной регистрации (с логином и паролем) — всё это в любом случае надо делать.
                      ну хотя бы получше чем вы сами
                      Это иллюзия. На самом деле «вы сами» — это вариант «неуловимого джо, который нафиг никому не нужен». А вот для крупных соц. сетей разработка утилит для массовой регистрации аккаунтов поставлена на поток — почитайте журнал «Хакер», там в каждом номере по паре (новых) таких утилит упоминается.
                      Поэтому мечты об удобном предпочитаемом логине user1, а не user1.OpenId-Provider-1 идут далеко и надолго.
                      Не вижу связи. Вы опять приплели к логинам email-ы. Предпочитаемый короткий логин/ник выдаётся в соответствии с ником юзера полученным по OpenID — если он свободен. Если он занят — юзеру предлагается выбрать другой короткий логин/ник. Email-ы здесь вообще не при чём.
                      …если мой провайдер кривой … сайт, который доверяет обоим провайдерам
                      Это проблема сайта. Не надо доверять кривым OpenID провайдерам, которые не проверяют email-ы. Вообще, речь вроде шла о доверии только 3-5 крупным сайтам, так что проблема надуманная.
                      • 0
                        идея openId именно в том, что сайт доверяет ЛЮБОМУ провайдеру, а не фиксированному набору, т.к. «любой провайдер» может быть вашим приватным и стоять на вашем сервере. Цель — единое место хранения ваших данных, чтобы сервера не хранили у себя их отдельно, а обновляли на основе ответа от некоего централизованного сервера ( вашего провайдера). чтобы вы могли свое имя поменять в провайдере и все сайты вас переименовали.
    • 0
      А как вы хотели? Вы получаете доступ к информации о пользователях. Держатели этой информации желают знать кто и зачем использует их сервис. Чтобы в случае чего блокировать ваше приложение и передавать ваши данные в соответствующие органы.
      • 0
        Речь об авторизации на сайте и не более.
        • +1
          И? В любом случае доступ к информации предоставляется.
  • +1
    Ребяты, я вот чего не понимаю.

    Пусть есть сайт, у него есть пользователи, зарегистрированные через email (классика), и есть пользователи, входящие через OAuth.

    Есть пользователь с ником Василий Иванович, которого все знают. И тут ему решил кто-то нагадить. Кто-то регистрируется неважно где с таким же именем, потом входит на сайт через OAuth, и совершает действия, порочащие доброе имя Василий Иваныча.

    Вопрос: как с этим бороться? Пользователя всеравно нужно показывать в своей системе с каким-то ником, даже если он зашел через OAuth. При классической регистрации два одинаковых ника не будет. При входе через OAuth — вполне себе обычная ситуация.

    Что делать?
    • 0
      Проверять уникальность ника. А что, есть другие варианты?
      • 0
        Т.е. даже после входа через OAuth у Вас должна появиться его учетка в БД. ID, Nickname и т.д.
        • 0
          Тогда в чем прелесто OAuth, если пользователь всеравно должен придумывать ник на сайте?

          И еще непонятно — как авторизовать пользователя после того, как у него оявится учетка на сайте? Снова через OAuth? Или требовать ввод пароля, чтоб потом авторизовать по логину-паролю?

          А если он же захочет войти из-под другого провайдера, то его нужно рассматривать как другую личность или как уже зарегистрированного пользователя? А по каким критериям? По нику + email? А если у него нет email?
          • +2
            1. Не «все равно», а в случае конфликта имен. Этого не избежать.
            2. Никто не мешает ему автоматом сгенерировать пароль (либо просто предоставить возможность указать пароль для входа через стандартную схему). Но и OAuth должен остаться доступным. Храните его OauthID (по идее, это комбинация oAuthID и ProviderID), потом всегда сможете проверить, существует ли учетка.
            3. Конечно, стоит проверять его email, и объединять учетки. Ник ни в коем случае не является показателем, в лучшем случае предложите указать свои прочие учетки (вход через них является подтверждением, т.е. email вроде и необязателен). Как-то так.

            На самом деле на Хабре есть несколько статей с подобным обсуждением, одну из них вроде и я создавал.
    • 0
      Изучать вопрос чуть глубже.

      Вы когда доверяете OAuth провайдеру — вы доверяете ему целиком. Например Facebook отдает вам емейл этого ВасильВаныча.
      Если Facebook позволил злоумышленнику зарегаться на почту ВасильВаныча и не проверил что почта действительно принадлежит тому, кто регистрируется- грош цена такому провайдеру, бежать оттуда и не доверять.
      Если же провайдер (я.ру) не позволяет регаться на чужую почту — то все ок, при входе через OAuth обычно следует запрос к API — «Вот у меня есть токен, скажи мне, сервис, какой email у того, кто мне этот токен авторизовал (а это был юзер)». Сервис тебе честно отвечает — email: vasil@vanych.ru.

      Все, если в бд уже есть такой зарегистрированный пользователь — того кто сидит на «другом конце интернета» можно логинить как этого пользователя.
      Если в бд нету — заводим нового, логиним.

      Если злоумышленник угонит аккаунт в ФБ — сможет зайти и к вам на сервис (это кстати серьезный вектор атаки), т.к. вы доверяете ФБ, а злодей смог его обмануть.
      Если злоумышленник угонит почту — очевидно что он сможет угнать и фб и ваш сайт, восстановив пароль на угнанную почту.

      Собственно надежность авторизации через сторонние сервисы — это доверие к этим сервисам, в том, что «их труднее сломать чем ваш собственный сервис».
      • 0
        PS: уникальные ники — зло, авторизуйте по email ;). В моем описании выше email от ника ничем не отличается, только вот я не видел провайдеров, которые гарантировали бы уникальность ника\имени. Зато уникальность email — гарантируется ;)
        • 0
          А если человек зареган у провайдера без email, то как быть?

          И я так и не понял, как отображать на сайте человека, зашедшего через OAuth. Проверять уникальность ника, и если ник неуникален требовать ввода другого ника?
          • 0
            Генерировать пользователю ник (user15646465) и выводить информер с предложением сменить ник.
            • 0
              Так, а что нужно сохранять в базе пользователей при первом входе через OAuth?

              Вот что вырисовывается:

              1. Случай если ник уникален:

              1. Ник
              2. email
              3. пароль — оставляем пустым
              4. флаг — регистрация по OAuth

              2. Случай если ник неуникален:

              1. Случайный ник типа user15646465
              2. email
              3. пароль — оставляем пустым
              4. флаг — регистрация по OAuth с неуникальным ником

              3. Случай если email не указан:

              Требовать указать email, не пуская дальше. После указания email проверяется уникальность. Если email неуникален — не пускаем дальше. Если email уникален, действуем далее по пункту 1 и 2.

              Так?

              • +2
                Вообще, рекомендую обратить внимание на такую вещь, как real_name. В том или ином виде он есть у всех вышеупомянутых провайдеров (в отличие от email). Я планирую вообще отказаться от того, чтобы логин где-то фигурировал на сайте, кроме как в странице входа. У меня входящие через OAuth получают ник вида vk_{VK_uid} — пусть некрасиво, но они (пользователи ВК) его и не видят. Все их сообщения подписываются их реальным именем. А регистрирующимся обычным путем при необходимости я сообщаю, что префикс vk_ — зарезервирован.
                • 0
                  > Все их сообщения подписываются их реальным именем.

                  Как люди друг друга будут различать, если имена у нескольких совпадут?

                  Ну то есть как другие пользователи будут понимать, что этот вася пупкин — это старенький, а этот вася пупкин — средненький, а этот вася пупкин — новенький?
                  • +1
                    несколько неполных совпадений (имя-фамилия) у меня есть. плюс, разумеется, всякие вовы путины и д.медведевы, которые всегда будут появляться, какие механизмы отсева не предусматривай. но с последними все понятно и без механизмов, а с первыми — никаких проблем не возникает. конфликтных ситуаций пока не возникало, и я их не предвижу. есть еще аватары, подписи, стиль сообщений и пр. да и не настолько часто они пересекаются, эти тезки — вы вот, IRL, когда крайний раз со своим полным тезкой встречались?
              • +1
                Я делал так: пользователь входит первый раз. Запрашиваю у oauth/openid email (это самый важный индентификатор). Генерирую пользователю ник (в любом случае). Далее все верно. Если провайдер oauth не отдает мыло — спрашиваю его у пользователя и не пускаю дальше. Пароль в данном случае вообще не нужен.
              • 0
                Можете пойти путем Ldap и создать DN. Что-то типа:
                CN=Karen Berge,CN=admin,DC=corp,DC=Fabrikam,DC=COM
          • 0
            писал длинный ответ, но он прохерился, то ли хабром то ли хромом. Больше ниасилю, извините.

            Вкратце — рассматривайте о-провайдера как способ получить «логин и пароль», если раньше вы спрашивали это у пользователя, то теперь есть третья сторона, которой доверяет и пользователь и вы, т.н. «удостоверяющая сторона» — УС. И эта УС сообщает вам «логин-пароль» для пользователя (логин- емейл, пароль например userid в сервисе, они не меняются ни у кого из провайдеров, хотя пароль в общем — не нужен, вы же доверяете УС когда она сообщает вам email).

            Но вам все равно прийдется заводить пользователя у себя в сервисе как и при обычной регистрации — все те же проверки, валидации и т.д.
            И логинить вы его будете также как при обычной авторизации, только логин-пароль вы получаете не напрямую, а через УС.

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

      • 0
        Не все сервисы из перечисленных выше отдают по API e-mail пользователя.
        • 0
          Именно так. И что?
    • 0
      Хе. Во первых в рамках одной соц. сети у вас клиенты будут уникальные. Если вам требуется уникальность на вашем сайте, можно или указывать откуда пришел пользователь т.е. уникальной должна быть связка пользователь-соц.сеть или же вы при первой регистрации выдаете пользователю форму со сменой ника на вашем ресурсе.
    • 0
      Так это же разные Василии Ивановичи. Надо их как-то наглядно отличать на сайте, а не показывать одинаково до степени смешения.
  • –1
    Вот только с OAuth 1.0 надо бы поосторожней. Я сам с твиттером еще не интегрировался ( ибо он, гад email не отдает, а мыло нужно), но насколько я помню — по стандарту OAuth 1.0 все параметры, подписываемые ключем, должны быть СПЕЦИАЛЬНО упорядочены:

    tools.ietf.org/html/rfc5849
    3.4.1.3.2. Parameters Normalization
    The parameters collected in Section 3.4.1.3 are normalized into a single string as follows:

    2. The parameters are sorted by name, using ascending byte value ordering. If two or more parameters share the same name, they are sorted by their value.

    (этот порядок еще называется lexicographical byte value ordering)

    Так что с «подставьте вот в эту строчку свое» — можно немного пролететь, если не помнить про этот порядок.
    • 0
      Можно просто после возвращение с твиттера показать страницу где пользователь должен ввести свой почтовый адрес. И подтвердить его на почте. Понятно что такое не удобно но многие такое практикуют. Все равно потом в другом браузере он сможет просто через твитер войти и сайт уже будет знать что у этого аккаунта твиттера такое-то мыло и уже дальше работать с пользователем. Например на сайте www.fashiolista.com/ (написан на python/django) именно так и сделано.
      • –1
        да, можно. Но нашего интерфейс дизайнера это раздражало, поэтому отказались от твиттера.
    • +1
      параметры в этой строке *уже* упорядочены
      • 0
        ага, только что сделает пользователь вашего кода, когда ему понадобится что-то добавить?
        Правильно, добавит в конец, т.к. http похрен на порядок параметров, и будет прав. А вот oauth — не похрен. Поэтому про специальное упорядочивание перед подписыванием — стоит упомянуть более явно.
        • +1
          упомянуто абзацем выше ;)
          • 0
            sort(parameters[]) у всех разный, да ;).

            Я зануда который наступил на грабли, поэтому обращаю внимание именно на ТИП сортировки параметров. У вас не указано.
            • 0
              Лениво :) я все ж надеюсь, что твиттер перейдет однажды а OAuth 2 и все станет проще. Google же перешел.
              • 0
                Уговорили… Про «ленивых в Security» часто рассказывают в новостях о про… теряных хэшах без соли и на инструктажах по технике безопасности ;)
  • +2
    Почему-то автор не упоминает о таком важном моменте как уникальный коллбек, для того чтобы можно было идентифицировать пользователя, возвращаемого oauth сервером. Чтобы коллбек был уникален, достаточно добавлять к redirect_uri какой-либо параметр и присваивать в качестве значение генерируемый хеш. А также записывать этот хеш в сессию и сравнивать после возврата пользователя на сайт.

    Иначе возможно атака в которой злоумышленник нажимает на ссылку авторизации, получает код, но не переходит на сайт для обмена кода на токен. Ссылка с кодом отдается жертве, и перейдя по ней, жертва привязывается к учетке злоумышленника. В результате злоумышленник может войти на сайт под видом жертвы.

    А OpenID в данной статье незаслуженно унижен. Не вижу никаких сложностей с тем чтобы явно указывать сервер авторизации openid в ссылке на сайте (войти через гугл, войти через жж). Что в данном случае меняется? Для пользователя абсолютно ничего. Он так же нажимает на ссылку, переходит на сайт гугла и разрешает авторизацию. Зато в качестве большого бонуса, не надо писать кучу кода. Там где только oauth — пишутся небольшие классы для общего интерфейса авторизации. Там где openid — меняется только адрес ссылки логина (site.com/login/?realm={google|yandex|etc...}) и используется единый класс с разными значениями auth_realm.
    • +1
      про уникальный коллбек я упомянул, читайте, пожалуйста, внимательнее, перед тем как предъявлять претензии. кстати, из упомянутых 7 сервис-провайдеров по-моему (не скажу, что на 100% уверен — специально не считал) только 3 разрешают менять коллбек непосредственно в запросе. Остальные — жестко посылают на юг, если коллбэк отличается от прописанного в натройках приложения.
      • +1
        Вк, фейсбук, твиттер, маил.ру, фликр — разрешают хеш в коллбеке. Для всего остального есть мастеркард OpenId. С одноклассниками не вязался еще, попробую :)
        • +1
          Упс, приношу извинения — параметры действительно работают. Недоглядел :\ все дело в mod_rewrite — у меня коллбэк — это параметр некоего общего для всех скрипта, и добавление еще одного параметра для сервера выглядело как изменение заданного в настройках коллбэка, на что он вполне заслуженно ругался. На нормальные параметры (через ?) они не ругаются. Завтра поправлю, когда высплюсь :)
      • 0
        остальные кстати правильно делают, вообще если приложение регалось и указало базовый урль то по стандарту надо слать в лес, если return_uri не на базовом.

        Если нельзя дописывать return_uri — есть параметр state, его все провайдеры по стандарту должны передавать без изменений (а реализация гугла тут «жжот» и нарушает) — по нему и ориентируемся.
        • 0
          >(а реализация гугла тут «жжот» и нарушает) — по нему и ориентируемся
          чем жжот она, простите? тоже стэйт передает вроде без проблем.

          хеш в редирект_ури это work around. в будущем redirect_uri будут статичны везде, это очевидно. use state
          • 0
            Стандарт (текущий) подразумевает проверку что return_uri находится на том же «пути» (домен) что и зарегистрирован в сервере, а не 100% совпадает. Гугль требует 100% совпадения.
            Тогда непонятно нахрена его передавать, если 100% совпадение с тем, что уже есть у гугла. тот же OAuth подразумевает что надо использовать зареганый, если не передано вообще. У гугла return_uri был required ( возможно сейчас поменяли)
            • 0
              все правильно. в будущем будет возможно регать несколько колбэков поэтому передавать надо. 100% совпадение — давно пора всем так делать.
              • –1
                Не убедили. Статичный на 100% коллбэк — многим известная дыра в OAuth. Возможность регать несколько колбэков проблему не решают.
                Если только эта возможность не будет доступна через API :)
                • –1
                  >Статичный на 100% коллбэк — многим известная дыра в OAuth
                  лол что, какая тут дыра, наоборот отличная защита.
                  ах, если вы про state то читайте другие мои комменты там даже есть видос, я предпочитаю его использование. csrf token в редирект_ури это прошлый век.
              • 0
                100% совпадение валидно, тут я прогнал немного, извиняюсь.
                просто оно блин сильно неудобно…
    • 0
      По OpenID. "(войти через гугл, войти через жж). Что в данном случае меняется?"
      "-"
      1. OAuth еще и дает мне доступ к API провайдера (что, в том числе, позволяет мне дать пользователю набор «вкусных» функций), а OpenID не дает ничего.
      2. Независимо от того, выполнен пользователем вход на OpenID-провайдере, или нет, он *должен* ввести у меня свой идентификатор
      "+"
      1. Мне не надо регистрироваться на провайдере.
      2. Мне не надо писать отдельную реализацию клиентской части для каждого очередного провайдера.

      Итог: если мы заботимся о пользователе — OAuth лучше, если о себе — OpenID
      • 0
        Давайте порассуждаем немного логически. Если сайт предоставляет уникальный функционал по работе с соц. сетями (работа с изображениями/фото/френдлента), то да, доступ к api, бесспорно, играет важную роль. Но в 90% случаев рядовых сайтов нужна просто авторизация.

        Теперь давайте про идентификатор. Разрешать какие-угодно внешние oauth/openid провайдеры, конечно, глупо. И в реальной жизни нашей целью скорее станет конкретный набор социальных сервисов. В случае с гуглом/яндеком для OpenId идентификаторы не нужны и, как я писал выше, для пользователя внешне все выглядит точно также.
        • 0
          Насчет первого — склонен согласиться. Я б даже сказал, что 95% рядовых сайтов той же loginзы хватило б выше крыши. Я про другой случай.

          А разве гугл/яндекс не пошлют меня лесом, если я отправлю к ним пользователя, не зная его идентификатор? ЖЖ, помнится мне, в таком случае прямо сообщал (причем не мне, а пользователю) что-то вроде: «сайт ХХХ попросил у вас идентификации, которую вы не можете предоставить» — после того, как юзер вводил свой логин и пароль на ЖЖ. Да и спецификации явно требуют передавать провайдеру идентификатор.
          • 0
            > А разве гугл/яндекс не пошлют меня лесом, если я отправлю к ним пользователя, не зная его идентификатор?

            Конкретно гугл и яндекс не пошлют. ЖЖ, блоггер и ряд других — пошлют. Попробуйте сами взять любую библиотеку openid для любого языка и скормить ей эти discovery url: www.google.com/accounts/o8/id
            openid.yandex.ru/
    • 0
      >Иначе возможно атака в которой злоумышленник нажимает на ссылку авторизации, получает код, но не переходит на сайт для обмена кода на токен. Ссылка с кодом отдается жертве, и перейдя по ней, жертва привязывается к учетке злоумышленника. В результате злоумышленник может войти на сайт под видом жертвы.

      true story www.youtube.com/watch?v=KRNsaPx7X-M&feature=g-hist
      • 0
        если злоумышленник может так сделать — это MitM, там такая сложная техника не нужна — фэйкаем сайт и перехватываем нативные логин-пароль. Остальное — overcomplicated.
        • 0
          вы не поняли техники, это не mitm. все делается очень элегантно и просто, одной лишь CSRF через
          • 0
            ну ютуб еще не смотрел. Но вообще если на вашем сайте можно каким-то образом разместить левую ссылку на сайт злодея — беда не в oAuth.

            А заключительный шаг обмена кода на access токен вообще не даст вашему приложению ничего, потому что токен максимум что — выдан для чужого приложения, маскирующегося под ваше, а стандарт требует на последнем этапе проверки client'а тоже.

            Это с ходу. Возможно в ютубе что-то интересное, но пока нет времени изучить — не могу обосновать.
            • 0
              зачем размещать на моем сайте? много кто разрешает размещать картинки или ссылки, но тем не менее что мешает разместиь на funnypictures.com/addr.html и подкинуть «жертве». очень легко.
              после проведения атаки производится disconnect from facebook — вообще никаких отпечатков.

              >А заключительный шаг обмена кода на access токен вообще не даст вашему приложению ничего, потому что токен максимум что — выдан для чужого приложения, маскирующегося под ваше, а стандарт требует на последнем этапе проверки client'а тоже.
              я все знаю. я не получаю access_token -он хранится на сервере. я вообще не трогаю oauth ресурсы жертвы. OAuth Callback Forgery
              • 0
                я посмотрю. Не могу прокомментировать прямо сейчас.
      • +1
        Посмотрел видео.
        Хомяков конечно крут, наверное…

        Но вот мне кажется он, или вы, допустили одну ошибку:
        Следующее высказывание, если все соблюдают протокол, НЕ верно (это цитата из вашего коммента, но в видео вроде суть похожая):
        «жертва привязывается к учетке злоумышленника».Попробую объяснить по шагам почему это не может быть ошибкой OAuth протокола (хотя с этим, как выясняется, у меня плохо, мутно объясняю).

        Действующие лица:
        Вы — сайт
        Юзер — человек сидящий напротив компа
        Злодей — тот кто перехватил свой редирект и хочет подсунуть его юзеру (в видео — Егор ;) ).
        ФБ — сервер OAuth 2.0, и по совместительству ресурс-провайдер, который по access-токену расскажет какой email и FB-ID у пользователя, который выдал токен.

        Итак, как на самом деле выглядит OAuth 2.0 процесс. Пропустим начало и перейдем к тому моменту, про которое говорится в видео. Как это в реальности:

        1. В результате перехода по редиректу с ФБ на return_uri, который демонстрировался в видео, вы, как сайт, получаете некий токен1 (авторизованный пользователем код), от ФБ. Никакой привязки к учетке конкретного юзера на сайте еще не произошло, как и не произошло логина его на сайт.

        2. В момент получения этого токен1, сайт должен сделать завершающий шаг — получить от ФБ Access токен и Refresh токен. Очевидно что канал между Сайтом и ФБ не скомпроментирован и там сайт может получить честный Access токен (а-токен) того пользователя, который сказал «да разрешить» и был отправлен редиректом ( это или юзер или злодей из видео.

        3. После получения a-токена, сайт может сделать только одно — обратиться за ресурсом к ФБ (который по совместительству...). Сайт передает токен и запрашивает страницу ФБ/me, чтобы получить информацию о том пользователе который подписал токен ( а сайт еще даже не знает кто это вообще).

        4. После получения данных о юзере, сайт принимает решение (это очевидно объязательный шаг.)
        4.1 если пользователь есть в БД (найден email для сайтового аккаунтХ или для маньяков — совпадение FB-Id для аккаунтаХ), сайт может смело залогинить юзера в аккаунтХ
        4.2 Если пользователя нет в БД — можно его зарегистрировать автоматически ( т.к. есть емейл и «оно проверено», ну еще сайты спрашивают другие обязательные поля, если их не отдал ФБ/me) и потом сразу залогинить

        Все. На этом шаге у нас есть некто, залогинившийся в аккаунтХ на сайте ( или некто, создавший АккаунтZ и залогиненный в него).

        Теперь вернемся к видео: для начала о чем рассказывает Егор — он рассказывает о библиотеке omniauth, это частная реализация протокола. Возможно в ней есть ошибка, хотя странно, т.к. спека довольно внятная и коряво ее сделать — надо постараться. И все же вернемся к самой «атаке».

        Предположение что теперь можно зайти с ФБ аккаунтом Злодея на сервис — верное, вы зайдете в тот аккаунт, который сделал или нашел для вас сайт (АккаунтХ — аккаунт зареганый на email злодея или АккаунтZ, созданный на основе email злодея).

        Но этот аккаунт привязан к собственному email злодея, т.к. шаг 3, на котором сайт запрашивает ФБ/me должен вернуть данные о том, кто авторизовал токен. А токен авторизовал злодей, и только потом он перехватил свой редирект и подсунул юзеру (редирект уже вел на сайт, на ФБ никто не ходил). Предполагать что с какого-то бодуна ФБ вернет данные произвольного юзера (неизвестного ФБ, т.к. запрос к me делает сайт, а там нет куки залогиненного фб юзера) — очень самонадеяно.

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

        Это все, что может произойти, если все стороны работают в соответствии с протоколом и без багов.

        Да, невнимательный юзер в этом случае может облажаться и оставить какие-нить данные в аккаунте злодея, но это НЕ атака НА ПРОТОКОЛ и это не сложнее того, что прийти за чужой комп и залогиниться в СВОЙ почтовый ящик, надеясь, что юзер отправит что-то по почте, а вы потом зайдете в свой ящик и почитаете это. Реализуемо, но это опять же, на 99% социальная атака, а не уязвимость протокола.

        Где может быть суровый косяк еще — в библиотеке OmniAuth ( о которой рассказывает Егор). Я не видел ее и не знаю, но по опыту имплементации OAuth2.0 в своем проекте — есть еще одна грабля (она кстати описана в хауту или даже в самом драфте вроде, надо смотреть, но это в общем не секретное знание):

        Если после редиректа юзер приходит на сайт и несет некий токен, а сам в это время уже залогинен на сайте ( есть Auth кука сайта) — сайт должен игнорировать токены и ничего из П.3-П.4 НЕ ДЕЛАТЬ.

        Допускаю (чисто эмпирически), что сайты описанные в видео, или даже сама OmniAuth НЕ проверяют залогиненность пользователя, когда тот приходит на Redirect_uri. И просто проводят все действия п.п.3-4 или сразу логинят, но где-то неправильно извлекают email и в итоге Access токен злодея действительно привязывается к учетке залогиненного пользователя.
        А еще к этому абзацу смотри NB в конце

        Это косяк сайтов, либы но никак не протокола OAuth 2.0. Так что или Егор ошибся (возможно, принял одну ошибку за другую), или вы неправильно интерпретировали видео (слишком короткий фрагмент, чтобы глубоко понять о чем вообще идет речь в докладе).

        Да, как можно этого избежать в 100% случаев. Шаг 4 должен делать следующее

        4.1 НЕ ЛОГИНИМ, а идем на новый п.5.
        4.2 Регистрируем Аккаунт, но не логиним, а идем на п.5

        п.5 Отправляем пользователя на авторизацию ПОВТОРНО, т.е. отправляем на подписание токена, со скопами и все такое, но очевидно с другим state, т.е. по сути имитируем повторное нажатие на кнопку «login with FB» на сайте.

        Т.к. ваше приложение честный юзер уже авторизовал ( это пока без злоумышленника), то все шаги пройдут незаметно для пользователя: логин на ФБ он уже недавно делал, приложению разрешения давал и все ок, если все правильно, то пользователь после 2х редиректов и еще одного запроса ФБ/me, только уже все без злодея ( который как-то подсунул ссылку ранее), пользователь окажется в СВОЕМ аккаунте, т.к. у него уже будет своя ссылка и он авторизовал токен ранее (т.е. у пользователя уже есть аккаунт на сайте).
        Если ранее была такая атака, то после этой процедуры юзер увидит окошко «приложение запрашивает разрешение», т.к. ваш сайт честным юзером еще не был авторизован, его, по истории, авторизовал злодей для своего аккаунта ФБ.

        Собственно все. Надеюсь описал понятно, готов защищать свою позицию даже против Егора, как автора предполагаемой ( кстати предполагаете вы, Егор не говорил что уязвимость в OAuth, описывается уязвимость в OmniAuth)

        NB: пересматривал видео после написания всего ответа, заметил упоминание именно такого момента (0:33 «Ставлю img src=этот коллбэк, подкидываю другому пользователю который в данный момент на этом сайте АУТЕНТИФИЦИРОВАН»). Собственно что я и сказал абзацем ранее — либа или сайт делают странные, неправильные вещи, они повторно аутентифицируют повторно пользователя, который УЖЕ АУТЕНТИФИЦИРОВАН.

        Извините но OAuth Callback ForgeryBUSTED!
        • 0
          в п.3 читать «сайт передает а-токен»

          … Интересно, этот коммент кто-нибудь осилит и осмыслит полностью при первом прочтении ;)?
        • 0
          ААА ну ненадо было столько текста я же пьяный;
          > кстати предполагаете вы, Егор не говорил что уязвимость в OAuth, описывается уязвимость в OmniAuth
          кстати этот егор это я. не буду отвечать на каждый из тезисов просто вкратце распишу свои.

          1; Oauth grant_type = code — web based — Очевидно. А любое web based lолжно защищаться от csrf это тоже очевидно. В основоном на редиректах реализации протокола защита должна быть встроена. Иначе ее тупо не будет. Insecure -by-default means insecure уже не раз это показывал )

          2. вы опять таки недоконца поняли суть современных авторизационных систем/
          есть МАСТЕР аккаунт на сайте pinterest.com есть FB аккаунт. Если бы был только ФБ логин то никаких проблем по логине в хакерский ФБ небыло бы, тк сидеть из под чужого акка не есть проблема. Но сейчас большинство(ну или много) работают по схеме МАСТЕР-СОЦИАЛ КОНЕКШЕНЫ.
          Задача хакера — прикрепить свой СОЦ КОНЕКШН к МАСТЕРу на сайте. после прикрепления он заходит через свой ФБ сразу в МАСТЕР юзера.

          2. и это не только уязвимость в omniauth. но и в огромном количестве других имплементаций включая самодельные(что и советуется в ОП посте)

          КАЖДАЯ деталь web based протокола должна быть продумана с точки зрения web based аттак. Оставлять это на откуп разработчика неправильно. исходя из этого это остается уязвимостью в oauth. пусть и зачастую потенциальной(если сайт не работает по схеме МАСТЕР-СОЦИАЛКИ а работает на основе самих социалок)
          • 0
            Ну привет, Егор ;).
            Жаль что не ознакомились, я вот ваше видео в итоге раза 4 пересмотрел, чтобы понять суть описываемой проблемы.

            Да, пока я действительно не понял что такое мастер аккаунт в ваших терминах.
            Мастер это акк на сайте Х, в который вы можете войти через ФБ ( т.е. есть у сайта связка «ФБ-что-то»-> Аккаунт1-на-сайте? )

            Если почитать OAuth, то за исключением удобства http\TLS — там вообще нет привязки к протоколу передачи данных. Можно взять и реализовать это на TCP\IP. Сурово но можно. Сам OAuth описывает порядок взаимодействия сторон,3-legged-oauth, а не то, как надо использовать http. Просто для удобства он полагается на http|s — так приводить примеры проще, иначе общая теория выносит мозг
            • 0
              Кстати если обратите внимание, стандарты на протоколы часто не регламентируют употребление конкретной версии или способа защиты типа TLS 1.2 или такой-то алгоритм шифования. Просто говорят — имплементатор должен сделать надежно, на момент написания стандарта надежным считается технология X версии 1.2.3.7 и алгоритм шифрования Y, не менее 1024 бит. Как вы понимаете, после окончательного утверждения стандарта, правки в него не очень удобно вносить, а уж следить за изменяющимся ландшафтом надежности TLS или криптоалгоритмов — вообще не дело авторов. Поэтому конкретное применение HTTP|S в стандарте не обозначает что этот конкретный стандарт может работать только по http|s, в случае с OAuth 2.0 можно реализовать протокол хоть на голубиной почте ( если определенным образом голубей «защитить» от перехвата и подмены). Поэтому рекомендации о конкретной защите от Web-Based атак в протоколе общего типа — бессмысленны и даже вредны, так как запутывает реализатора.
          • 0
            Давайте попробуем кратко и по существу ;)
            1. Вы утверждаете что уязвим протокол OAuth 2.0 или уязвима конкретная либа, его реализующая, omniauth?
            1.1 Если либа — вопросов нет, криворуких программистов на свете много и их либы — довольно жалкие поделия.
            1.2 Если говорите что сама концепция ( а «протокол» это порядок действий и соглашение о форматах) OAuth 2.0, то будьте любезны просмотреть драфт протокола и сказать какое именно место протокола уязвимо.

            Это 2 очень принципиальных поинта — уязвимость реализации и уязвимость всей идеи. Хочется точно понять, что именно вы утверждаете.

            Я вот утверждаю, что идея прописана правильно ( возможно в ней есть еще мелкие недочеты, но не фундаментальные ошибки), а конкретные либы, как частная реализация идеи — не интересны.

            2. Поясните что же именно скрывается под мастер аккаунтом, потому как я не понимаю, из видео — это какой-то аккаунт на сайте, не более того.

            3. Если вы настаиваете что идея уязвима, а не либа, предложу в PM способ проверить уязвимость идеи на примере конкретного сайта, в котором есть Login With Facebook и где не составит проблем понять, действительно ли проблема в протоколе или проблема в реализации. Я, юзер, перейду по сформированной вами ссылке-редиректу на этот сайт с токеном FB. Открою честно, в In-Private режиме Google Chrome, чтобы не было шансов того, что я залогинен. После этого если вы скажете содержимое моей текущей истории на сайте (а вы предполагаете что потом вы сможете зайти со своим ФБ в мой мастер? аккаунт, правильно же), мы обнародуем результаты и наверное прославимся, т.к. найдем фундаментальную уязвимость в протоколе OAuth 2.0.

            Устраивает?
    • 0
      Почитайте мой коммент ниже, такая привязка не проблема протокола…
  • +1
    Плюсики, избранное.
    Сейчас активных проектов нет, но когда займусь в очередной раз чем-то, то прикручу 100%!

    А у ЖЖ этой фишки нет, или не стали делать? Вроде я на сайтах «Залогиниться через ЖЖ» видел?
    • 0
      У них есть OpenID. Но они бяки: кроме собственно аутентификации, ничего предоставляют — ни email, ни реалнейм — по OpenID не отдают.
  • 0
    Не нравится мне мода делать вход только через социалки, не хочу я давать вам доступ к своим аккаунтам!
    • 0
      Я примерно об эом и гвоорил когда писал про BrowserID
    • +2
      no problem. у меня на сайтах альтернативный вариант всегда есть — региструйтесь, вводите капчу, ждите письмо на ящик со сгенеренным паролем :)

      а мне наоборот, мода ужасно нравится — завел себе специальный аккаунт на фейсбуке, через который вхожу на все сайты, где есть вход через соцсети :) огорчает только, что не на всех сайтах он есть :(
  • 0
    Спасибо за статью!
    Не могли бы вы пояснить еще один момент: как лучше реализовывать обработку таймаута логин состояния? Полученный токен же имеет время жизни?
    • +1
      Увы, у всех по-разному. Читайте API :( некоторые присылают refresh_token, с которым нужно получать новый access_token. У кого-то токен бессмертный (впрочем, зависит от затребованных прав) и новый не нужен. К сожалению, большинство критиков OAuth правы — даже в рамках потока аутентификации, каждый извращается кто во что горазд. Я здесь описал необходимый *минимум*, который нужен для входа на сайт через OAuth. Еще раз скажу вышеописанного недостаточно для надежной и безопасной авторизации. Но этого достаточно, чтобы знать где рыть и как сделать «все хорошо».
      Про обновление токена я собирался написать в следующей статье — о интеграции инструментов социалок на свои сайты. Пока у меня даже не по всем есть вся инфа. Но это попозже, когда будет время.
      • 0
        С нетерпением ждём вашу следующую статью!
      • 0
        Читайте драфт стандарта — там это валидный сценарий. А вот насчет недостаточно — хотелось бы послушать, очч любопытна «экспертиза» в этом вопросе.
        • 0
          Я про это упомянул. Что не уделил внимания ни вопросам безопасности, ни воросам обовления токена. ни тупо неуспешным течениям, которые (о, сюрприз!) у всех провайдеров тоже разные, и которые неплохо было бы адекватно парсить. Давно планирую опубликовать развернутую статью о безопасности OAuth (с конкретикой, разумеется), но все не доходят руки. Планов громадье, как обычно, а времени — увы.
          • 0
            Мну интересует что же вы подразумеваете под «вышеописанного недостаточно для надежной и безопасной авторизации», ибо пока что я не согласен, а слушать «критиков OAuth» — ну так 3.14здеть это не мешки ворочать. А вот о «проблемах по существу» еще ни разу не слышал, все как-то соскальзывают или оказывается проблема не в OAuth 2.0.

            Удобство — да, не всегда еще удобно, стандарта-то финального нет, только черновики. А вот сомнения в надежности — очень любопытно послушать
        • 0
          О неуспешных течениях. Одоклассники (ох уж эти одноклассники) даже в неуспешном течении возвращают 200 OK — но с описанием ошибки в теле ответа :)
          • 0
            Подозреваю даже — почему так. Есть маленькая проблема, например, с .NET — когда делается ручной вызов а-ля userInfo через класс WebRequest\WebClient, то любые ответы «НЕ 20x» приводят к вылету соответствующего исключения. Строить бизнес-логику на исключениях — не комильфо, а в спеке написано что регулируется только поле error, остальное — на усмотрение авторов.

            7.2 Error Response

            The OAuth resource access error registration requirement applies only
            to «error» code values and not to other means of returning error
            indications, including HTTP status codes
            , or other error-related
            result parameters, such as «error_description», «error_uri», or other
            kinds of error status return methods that may be employed by the
            resource access method. There is no requirement that OAuth resource
            access methods employ an «error» parameter.
            BTW внутренний сервер у нас поступает точно так же — возвращает 200 и правильное поле error. Это торчат уши используемой платформы.
  • +1
    > Потому что некоторые ресурсы не поддерживают response_type=token.

    это какие?

    >GET oauth.vk.com/access_token?client_id={client_id}&client_secret={secret_key}& code=7a6fa4dff77a228eeda56603b8f53806c883f011c40b72630bb50df056f6479e52a//полученный в параметрах код

    полное несоответствие oauth2 ieft!!! токен должен выпускаться для конкретного redirect_uri и он должен быть параметром для получения тоекна. это банальная csrf дыра, ну что за бред

    >sign — трахнутая на все байты md5-подпись
    для того и делали https based oauth2 чтобы не париться с подписями. Why, одноклассники? хотя у вас лучше чем у вк.

    >1. Здесь OAuth 1.0 и тут всё веселее
    да, у твиттера фейл =/

    а у яндекса менее гибкое api, хотя статичный redirect_uri неплохое решение

    не вижу в статье упоминания state :trollface:
    • 0
      >это какие?

      одноклассники и майлру response_type=token не поддерживают. мне показалось логичным расписать течение, которое поддерживают все упомянутые провайдеры. как-то проще для админа.

      >полное несоответствие oauth2 ieft!!!
      и не единственное. а я-то при чем? :)

      >не вижу в статье упоминания state
      Как это? Вот же… а…
      Тьфу, блин — не scope, а state. *confused* поздно было, не заметил, ща исправлю.
      Не всеми он поддерживается, вот из общего списка параметров я его и выкинул.

      • 0
        так это отлично. response_type = token это очень плохо. reveal токена это худшее то может стать с ресурсом. это хуже xss8 grant_type = code самый лучший вариант и всем рекомендую его использовать

        то что он не всеми поддерживатся это фейл, нужно плевать в тех кто не поддерживат. Тьфу вк!
  • –2
    Совершенно несправедливое отношение к OpenID.
    Сегодня любой почтовик имеет свой OpenID-сервер: Гугл, Яндекс, Яху, Рамблер и даже Мейлру!
    А самое главное, что OpenID предоставляет мыло, что позволяет вписать его почти в любую систему авторизации. А хваленый OAuth отдает айдишники пользователя, и как их приаязывать к модели пользователя, где емейл обязателен, не понятно. Вот почему после авторизации через FB/Twitter меня заставляют вводить дополнительные данные, что только затягивает процедуру входа.
    • 0
      fb отдает email насколько я помню. В остальном — генерирую randomhash@mysite.com и пусть юзер обновит если надо
      • 0
        FB да, а твиттер нет, к сожалению.
      • 0
        Сурово, а если пользователь забыл обновить, а потом забыл пароль — хочет восстановить. Вы ему куда восстановление отправите? Выход только один — или требовать ввод email до того как пользователь пойдет дальше или пользоваться провайдерами которые отдают email сами.

        Твиттер не отдает и поэтому когда\если мы будем делать твиттер — мы будем заставлять пользователей вводить email, как единственное дополнительное но обязательное поле. Интерфейс-дизайнер хочет сделать это просто навязчивой плашкой, где будут нудеть — «у нас нету вашего email, доступ к некоторым разделам сайта будет ограничен и т.д», что в принципе — вариант неплохой.
    • +1
      >Вот почему после авторизации через FB/Twitter меня заставляют вводить дополнительные данные, что только затягивает процедуру входа.

      Прошу заметить что это затягивает процедуру не входа а регистрации. Только при регистрации нужно спросить почту юзера а потом он так-же спокойно будет входить одним нажатием точно так-же как если бы его вообще не спрашивали о почте. Тут можно совершенно определенно сказать что это удобно. Ибо пользователь может и не вспомнить на какую из десятков почт он регился на этом сайте и какой у него пароль… а нажав на кнопочку войти через твиттер, он спокойно войдет не вводя никакую почту(ибо он при самом первом входе ее уже ввел).
    • 0
      «Гугл, Яндекс, Яху, Рамблер и даже Мейлру!» имеют также и OAuth, а через API спокойно отдают емайл пользователя и еще много чего. Покажите мне сервис, который через OpenID дает больше информации о пользователе, чем через OAuth.
  • 0
    Спасибо за интересную статью, как раз недавно сталкивался с oAuth2 для проекта на GAE, но не осилил. С этой статьей попробую ещё раз.
  • 0
    Как же вы вовремя, съэкономили мне кучу времени
  • 0
    Интересно, а на каком-нибудь из этих сервисов поддерживается 2-LEGGED OAuth?
  • 0
    Большое спасибо за статью. Единственный момент про Твиттер — на РНР с ним можно обойтись функицей file_get_contents и вместо заголовка собирать строку запроса. Ну и в третий раз собирать подпись унд заголовок нет смысла, поскольку после второго получаем идентификатор и имя пользователя, которые спокойно подставляются вот сюда:

    twitter.com/users/show.json?screen_name=['screen_name']
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Эх, по тумблеру бы кто-ниубдь написал авторизацию. А то я задолбался: там вроде все так же, как в твиттере, но нифига не работает! Все время неправильная сигнатура.
  • 0
    Спасибо автору за систематизированный степ-бай-степ мануал. Единственная статья в рунете дающая исчерпывающее и «без мусора» пояснение. Учитывая прошедшее время неплохо было бы актуализировать некоторые моменты — скрины и ссылки. Интерфейсы разработчиков меняются, опции оказываются в других местах. К примеру у контакта создание приложения теперь тут: http://vk.com/editapp?act=create, фейсбук отказался от группы настроек AuthDialog и раскидал их по другим группам. Также важным было бы упомянуть, что например, Контакт, не отдаёт через API email пользователя — это бы избавило многих от лишних поисков ответа.
  • 0
    Уже имею подключенные все сервисы через oAuth и в своё время долго грыз эту науку. Хорошая статья.
    На всякий случай сохраню в избранное — удобно в одном месте все популярные сайты собраны.

    P.S. И когда твиттер разродится на oauth 2?..
  • 0
    При получении access_token для социальной сети ВКонтакте теперь нужно обязательно передавать redirect_uri + можно уже делать и POST-запрос, а у Twitter изменился адрес API: https://api.twitter.com/1.1/ — просьба исправить.

    Автору большое спасибо за статью!
  • 0
    Почему твиттер oauth is so fucked up?
  • 0
    Только благодаря вашей статье разобрался с работой api моего мира, официальная документация оставляет желать. Спасибо!
  • 0
    На моем ресурсе (аудиотека лекций) все сервисы были доступны без регистрации. В месяц регистрировалось в среднем 1,5K юзеров. Затем я закрыл доступ и ввел обязательную регистрацию. Стало регистрироваться 3,5К юзеров а траффик вообще не просел. Тех кто кривится рожей при виде формы регистрации на самом деле по моей личной статистике не больше 5%, но это именно они пишут обычно, что регистрация бесит ВСЕХ…
    • 0
      Регистрация бесит, возможно, не всех, просто не все, кого она бесит вам об этом сообщают. Проверьте на досуге сколько из ваших 3.5К юзеров сделали регистрацию на одноразовое мыло, можете смело получившееся значение умножить на 10, т.к. большинство про такую возможность не знают — это те, кому ваша регистрация никуда не уперлась кроме как для получения файлов.
      • 0
        Всё уже на доусуге проверено и отфильтровано. Одноразовых ящиков пренебрежимо мало, настоллько что даже и говорить не о чем. Волзможно дело в том что у меня просто более культурная аудитория.А умножать на десять просто исходя из чьих то предрассудков по моему глупо. Слишком уж раздутая проблема.
        • +1
          у меня просто более культурная аудитория

          Как тонко вы всех обосрали…

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

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.