Авторизация через ВКонтакте на PHP –

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

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

Почему oauth, а не openid?

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

Во-первых, OpenID пользуются в основном «гики», процент которых в интернете не настолько высок, чтобы перестраивать под них сайты (за некоторым исключением, разумеется 🙂 ) Почему так? Потому что для того, чтобы получить OpenID аккаунт, надо — его получить.

Зайти на OpenID сервер и предпринять некоторые действия, чтобы заполучить некий, довольно невразумительный, набор символов. Который, несмотря на сложность (для простого пользователя) надо не забыть и вводить при случае, если на глаза попадется знакомая пиктограмма

image

. Ну какой казуальный пользователь будет это делать? А с OAuth все намного проще — видит человек кнопку «Войти через ВКонтакте», нажимает, и… уже на сайте с правами зарегистрированного пользователя. «Будьте проще», — говорил классик, — «и люди к вам потянутся». Как в воду глядел.

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

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

Похожее:  Двухэтапная аутентификация — Справка

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

Кроме того, OpenID аутентификация, в сущности, не дает никаких гарантий клиенту. Она подтверждает лишь, что запрашиваемый пользователь действительно зарегистрирован на одном из OpenID-серверов — и все. Механизмы получения дополнительной информации о пользователе (email, имя, возраст) имеются, но мало кем поддерживаются.

Можно, конечно, в нарушение идей OpenID, анализировать идентификатор и доверять только определенным OpenID-провайдерам (например, тем же социалкам). Но смысл, если почти все из них (за исключением ЖЖ, но он и по OpenID ровным счетом ничего не расскажет о пользователе)

Авторизация через вконтакте, и другие для самых начинающих — 1

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

Итак, начнем с ВКонтакте. Заходим на

страницу подключения сайта

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

управления приложениями

, там мы узнаем ID приложения и секретный ключ, который естественно раскрывать никому нельзя.

На странице, на которой предполагается кнопочка «Войти через ВКонтакте» требуется добавить в head страницы

<scripttype="text/javascript"src="http://userapi.com/js/api/openapi.js?34"></script>

И инициализировать приложение:

VK.init({apiId: __APP_ID___});

Теперь нужно показать пользователю кнопку через вызов виджета. В качестве параметров Auth принимает id элемента, в который нужно отобразить виджет, ширину и адрес страницы, куда мы будем перенаправлены после попытки доступа.

      <divid="vk_auth"></div>
<scripttype="text/javascript">
VK.Widgets.Auth("vk_auth", {width: "300px", authUrl: '/vklogin.php?'});
</script>

Что увидит пользователь:

Авторизация через ВКонтакте на PHP -

После щелчка на «Войти через ВКонтакте» пользователя кидает на страницу вида vkontakte.ru/widget_auth.php?act=a_auth_user&app=__APP_ID__&hash=d2d47b3c85d1a091a8, затем на url, указанный вами в параметре AuthUrl при вызове виджета. Кидает со следующими GET параметрами:
first_name (имя), hash (используется для проверки того действительно ли запрос пришел от контакта, а не хакер Вася пытается авторизоваться под чужими данными), last_name (Фамилия), photo (большая аватарка, 119 пикселей шириной), photo_rec (маленькая аватарка, 50х50), uid (id пользователя). Пришедшие к нам параметры я после фильтрации сохранил с такими же именами в глобальной области видимости.
Теперь нам нужно сделать скрипт vklogin.php, в котором мы будем проверять правильность пришедших данных и, либо авторизовывать пользователя если он уже есть в нашей базе, либо создавать новый аккаунт для пользователя зашедшего к нам впервые.

if ($_REQUEST['hash']==md5('2445355'.$uid.'__SECRET_KEY__')) {
//доверяем вконтактику, и далее полагаем, что пользователь действительно авторизован там
//для учетных записей пользователей я решил выделить логины вида vk-********
$result = mysql_query("SELECT id, random, password FROM tracker_users WHERE username = 'vk-$uid'");
setcookie('uid','');
setcookie('pass','');
if (mysql_num_rows($result)) {
//пользователь авторизован, просто пересоздадим куки
$user = mysql_fetch_assoc($result);
mysql_query("UPDATE tracker_users SET name = '$name' WHERE username = 'vk-$uid' LIMIT 1");
setcookie('pass',md5($user['random'].$user['password'].$user['random']));
setcookie('uid',$user['id']);
} else {
//добавим запись в таблицу пользователей
$random = mt_rand(100000,999999);
$pwd = $uid . 'verysecretlonglongword-';
$pid=md5(uniqid(rand(),true));
mysql_query("INSERT INTO tracker_users
(username, name, password, random, id_level, email, style, language, flag, joined, lastconnect, pid, time_offset) VALUES
('vk-$uid', '$name', '"
. md5($pwd) . "', $random, 3, '', 5, 7, 0, NOW(), NOW(),'$pid', '0')");
//вставили строчку, теперь создадим куки и перебросим на другую страницу
setcookie('pass',md5($random.md5($pwd).$random));
setcookie('uid',mysql_insert_id());
}
header("Location: /index.php");
}

* This source code was highlighted with Source Code Highlighter.

На сайте, на котором мне необходимо было сделать авторизацию в куках сохраняется id пользователя и хеш от соли и хеша пароля. Решение, конечно, не идеальное, но менять полностью весь движок в мои планы не входило. Если пользователь у нас уже есть мы его авторизуем, создав куки, если он впервые, то добавляем его в базу. Также при каждом заходе мы обновляем данные об именах, потому что пользователь мог его поменять, а мы хотим актуальности.

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

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

Авторизация через ВКонтакте на PHP -

Если уровень и тематика статьи интересна хабрапользоватям, то я продолжу с майл.ру, facebook и твиттером.

Вторая часть. Mail.ru

Google

1. Идем

. Создаем новый проект. На вкладке API access нажимаем кнопку «Create an OAuth2 client ID».

image

Получаем client_id(Client ID) и secret_key(Client Secret).

image

2. Код кнопки должен быть вида:

Авторизация через вконтакте api.

Авторизация через ВКонтакте на PHP -

Важно:

Также очень важное значение v, без него вообще не чего работать не будит, он указывает версию API.

Вконтакте

1. Идем

. Тип — «Веб-сайт». Вводим базовый домен и адрес сайта. На странице настроек получаем client_id (ID приложения) и secret_key (защищенный ключ).

image

2. Втыкаем в код кнопку вида

Делаем авторизацию через вк:

Теперь посмотрим как делается сама авторизация через ВК на PHP, для этого, сначала нужно создать кнопку, которая будет отсылать во ВК, но перед этим сделаем файл config.php, в котором будим хранить нужные нам данные.

В этом файле просто хранятся константы нужных данных нашего приложения.

Теперь создаём страницу авторизации, вот она.

Тут просто подключаем файл «config.php» и создаём ссылку для входа через ВКонтакте.

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

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

Потом когда мы перейдём где будем обрабатывать основную авторизацию, у нас будет GET запрос, но об этом позже.

Также есть ещё два значения в запросе, это client_id в нём передаём ID приложения, а второй это display, тут указывается тип страницы для авторизации, у нас это page, которая используется для обычных WEB сайтов.

Вот как у нас выглядит страница.

Кнопка для входя через ВК

Теперь перейдём к обработчику авторизации и получению данных пользователя.

Тут уже всё сложнее, сперва мы проверяем, есть ли вообще код, для последующей работе с авторизацией, если нет, то прерываем программу, если да, то делаем URL запрос.

В этом GET запросе можете заметить несколько значений два из них знакомы, о них можете ознакомится выше, остальные сейчас разберём.

Первый, client_secret, это наш защищённый ключ, второе значение code код который у нас есть из GET запроса.

После этого мы отправляем GET запрос с помощью функции file_get_contents(), в качестве ответа, она вернёт JSON массив, который не читается PHP, поэтому мы объявляем функцию внутри другой функции json_decode(), которая декодирует формат JSON, в качестве второго параметр она принимает true, что означает декодирование в обычный ассоциативный массив PHP, это массив присваиваем переменной $token.

После чего опять проверяем, имеет ли значение переменная $token, если нет, то останавливаем программу и выводим сообщение, если да то опять делаем URL запрос.

Как быть?

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

С документации мы можем узнать что Параметр sig равен md5 от конкатенации следующих строк:

Давайте получим информацию о пользователе через open api, передадим её на сервер, проверим токен, и если все ок запишем в базу:

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

Если кому интересны все подробности, то см. ссылки выше. А вкратце — так:

Настройка ссылки для входа

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

Одноклассники

1. Регистрируемся как разработчик

. Идем

и заполняем заявку на получение OAuth доступа. Н-да. Заявка, похоже, обрабатывается вручную. Если ответа в течение суток нет, пинаем поддержку по тому же адресу. «Одноклассники», что тут скажешь…

2. Получаем письмо с инструкциями и, следуя им, заполняем форму.

image


Все заполненные в примере поля обязательны к заполнению. Нажимаем «Сохранить» и получаем письмо на указанный емайл, содержащее client_id(Application ID), public_key(Публичный ключ приложения) и secret_key(Секретный ключ приложения)

3. Код кнопки должен быть вида:

Получение данных из вконтакте

И так, пропишем скрипт получения данных от vk по только что присланному code. 

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

Разумеется, в первую очередь надо зарегистрироваться в соцсети, активировать аккаунт, ну и всё такое. Не торопиться. Некоторые сервера не сразу корректно обрабатывают запросы от свежезарегистрированных OAuth-клиентов. Здесь я расписал только успешные потоки, забывать про обработку ошибок — никак не стоит.

Также я практически не уделил внимания аспектам безопасности — это тема отдельной статьи. Как минимум, везде, где можно передавать уникальный параметр в callback-url для каждого пользователя — это стоит делать (Основной callback адрес должен оставаться без изменений, а меняться — только параметр, иначе сервер не пропустит запрос.

Проблема 1

Полученный токен(sig) привязывается к ip-адресу, и при попытке использовать его на сервере вам выдаст ошибку:

Проблема 2


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

Проверка авторизации

Давайте создадим модель, которая будет содержать информацию о пользователе:

Регистрация приложения

В первую очередь создайте приложение на странице 

Создание приложения во вконтакте:

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

Кнопка "разработчикам" Вконтакте

Также можете перейти по этой ссылки.

Там же нажимаем сверху на вкладку мои приложения.

Меню для ВК разработчиков

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

Добавление сайта в API ВК

Тут думаю всё понятно, единственное, для некоторых может быть не понятным, что такое базовый домен, тут просто нужно вписать доменное имя своего сайта, нажимаем «Подключить сайт».

После того как создали сайт, заходим в настройки этого сайта и там самое главное, это три пункта, «ID приложения», «Защищённый ключ» и «Доверенный redirect URI», последнее это поле, в него вы должны вписать где будет обрабатыватся авторизация.

Яндекс

1. Идем

Вывод:

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *