Авторизация на Drupal-сайте с помощью аккаунта ВКонтакте

Submitted by Ромка on Пнд, 17/05/2010 - 00:26

Ромка аватар

Разработчики ВКонтакте.ру не так давно открыли доступ к OpenAPI — интерфейсу, позволяющему обычным пользователям авторизоваться на сторонних сайтах с использованием своих учетных записей ВКонтакте.ру.

Я выкладываю первую версию модуля vk_openapi, который интегрирует Drupal 6 с Open API. Демонстрацию работы модуля вы можете увидеть на этом сайте. Кнопка для авторизации с помощью учетной записи вКонтакте находится в форме авторизации (в правой колонке внизу) и на странице с формой входа.

Особенности модуля

  • из учетной записи ВКонтакте выбираются все доступные поля и сохраняются в объекте $user;
  • каждому созданному модулем пользователю автоматически может быть назначена роль;
  • в качестве аватара нового пользователя может быть использован автар из профиля пользователя ВКонтакте;
  • созданный модулем пользователь может быть связан с существующим на сайте аккаунтом.

В ближайших планах: обновление статуса пользователя на основе данных из профиля ВКонтакте.

Скачать модуль можно на drupal.org. В продолжении более подробное описание модуля и инструкция по его установке.

Работа модуля

Это пока первая и очень простая реализация модуля, работает он так:

  1. после нажатия пользователем кнопки "войти вКонтакте" модуль получает необходимые данные от сервера вКонтакте.
  2. Далее модуль проверяет есть ли в базе данных Друпала пользователь, связанный с именем, полученным от вКонтакте:
    • если его нет, то создается новый пользователь и связывается с id пользователя ВКонтакте. Внимание! Важная деталь. Если в базе данных есть пользователь с именем не связанным с учетной записью вКонтакте и из вКонтакте приходит пользователь с таким же именем, то такие две учетные записи не будут связаны, для имени нового пользователя будет просто добавлен суффикс _N, где вместо N будет подставлено число.
    • если связанный с учетной записью ВКонтакте пользователь есть, то будет использована найденная учетная запись.
  3. Выбранный пользователь авторизуется в системе.
  4. ВКонтакте не отдает адрес электронной почты, по этому модуль предлагает новому пользователю указать свой e-mail в настройках своего нового аккаунта.

Установка и настройка модуля

  1. Первым делом во ВКонтакте нужно создать приложение типа "Веб-сайт", для этого нужно перейти по ссылке: http://vkontakte.ru/pages.php?act=developers и нажать на кнопку "Подключить сайт".
  2. В настройках созданного приложения нужно указать адрес сайта (http://example.com/) и базовый домен (example.com), а также получить ID приложения и защищенный ключ, все эти четыре параметра нужно будет указать в настройках модуля vk_openapi.
  3. Теперь нужно скачать модуль, если вы этого еще не сделали, распаковать в папку sites/all/modules и включить его стандартными средствами Друпала.
  4. После активации модуля, на странице admin/settings/vk_openapi вы должны указать параметры созданного ранее приложения ВКонтакте.

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

  1. <div id="vk_login" class="vk_login" style="margin: 0 auto 20px auto;" onclick="doLogin();"></div>

который будет заменен на кнопку.

Я старался сделать этот модуль максимально простым для посетителей сайта — авторизоваться в системе можно всего одним кликом. Мне, например, сильно не нравится реализация Facebook Connect для Друпла тем, что после нажатия кнопки "Connect" пользователя заставляют еще заполнить некоторые поля в форме регистрации. По этому данные от ВКонтакте получаются только один раз, при первом входе в систему, и используются только имя и фамилия пользователя. Теоретически, эти данные можно периодически обновлять, также есть возможность получить данные о фотографиях пользователя и его аватарке, его друзьях изменениях статусов, связать логаут на Друпал-сайте с логаутом из ВКонтакте и т.п. Интересно знать нужен ли кому-нибудь подобный функционал или достаточно того, что уже есть сейчас?

168 Comments

Кнопка в Opera 10.53 —

Кнопка в Opera 10.53 — http://img97.imageshack.us/img97/6723/20100517014838.png

Аналогично :(

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

надо!

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

Ромка аватар

Кнопка в Opera 10.53 —

Кнопка в Opera 10.53 — http://img97.imageshack.us/img97/6723/20100517014838.png

Подтверждаю. Аналогичный глюк выскочил в Опере и у меня.

Роман, проверте кодировку. У кнопки кодировка - cp1251, а у страницы - utf8.

Тут проблема в том, что кнопку отдает сам вконтакт вот этим скриптом: http://vkontakte.ru/js/api/openapi.js. Сейчас попробую разобраться как конвертнуть в utf8 полученный код кнопки.

Было бы замечательно -

Было бы замечательно - получать аватар пользователя Вконтакте и присваивать его новому пользователю. Так же хорошо сделать двухсторонний logout.

После нажатия на кнопку

После нажатия на кнопку авторизация не происходит. Кроме того идет зацикленное соединение с вконтакте.

Ромка аватар

Какой браузер и ОС? Включен

Какой браузер и ОС? Включен ли java-script (хотя похоже что включен)? Может какие-то еще данные сообщите, по которым проблему можно будет локализовать?

Имя пользователя

Ром, "контакт" недавно добавил ники, вероятно до них можно достучаться через данное АПИ.

А так получается что name = ФИО которые могут меняться ...

$account->name = check_plain($first_name . ' ' . $last_name);
Сие очень плохо! check_plain нужно использовать только при выводе информации, а полученные данные сохранять в исходном виде.

С нетерпением жду анонса на d.org

Ромка аватар

Сие очень плохо! check_plain

Сие очень плохо! check_plain нужно использовать только при выводе информации, а полученные данные сохранять в исходном виде.

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

"Лишние" символы

Полагаю, что лучше пользоваться
http://api.drupal.org/api/function/drupal_substr/6 или
http://api.drupal.org/api/function/truncate_utf8/6

C JS засада... разве они не передают информацию стандартным POST GET?
- иначе придется конвертить данные из 1251...

Видимо cыроват их api

Тут должна бить тема комментария.

Здравствуй Ромка
из Евросоюза.

По счастливой случайности нагуглил твой модуль - молодца. Теперь благодаря тебе у нас будет авторизация через всесоюзную социальную сеть. Сам пока толком не знаю, как понимать этот OpenAPI - победа амбиций Павлика Дурова & Co над здравым разумом или наш ответ западу на них OpenID, OAuth и FacebookConnect.

Так вот, о модуле, работает безупречно, но хотелось бы как в twitter обновлять свой статус вконтакте. Заходишь в «My account», кликаешь по закладке «Вконтакте», прописываешь e-mail, пароль и даже при помощи элементарного microblog обновляешь свой статус.

Начал изучать OpenAPI и наткнулся на http://habrahabr.ru/blogs/php/93037/ «как оказалось, сессия при авторизации выдается всего на час, что для задачи явно не подходит. В итоге решено было пойти путем эмуляции и сделать логин и авторизацию через cookies». Значит или делать при помощи OpenAPI с перелогиниванием (филологи меня простят) каждый час или авторизацию через cookies. Какой метод ты считаешь наиболее подходящим для этой задачи.

Полезная ссылка...

Видать контакт таки страдает отечественным "сделаем-все-по-своему"

но сыровато мля...

PS: Ромка, поставь http://drupal.org/project/comment_notify авторизованным то пользователям-то удобнее на мыл получать оповещения о коментах!

Не могли бы Вы подсказать:

Не могли бы Вы подсказать: как вывести кнопку "Войти Вконтакте" обособленно без формы авторизации.. ? Хотелось бы её добавить в футер страницы в виде "блока", но без объёмной друпаловской формы.

После авторизации через API

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

Ромка аватар

Ну да, это так и задумано. На

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

спасибо, попробуем

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

страница вКонтакте

Аватар и прочие данные важнее не разово вытаскивать, а иметь возможность синхронизировать, при каких-нить условиях

А вот насчет ссылки на страницу профиля ... что-то вроде было, типа списка своих профайлов в других социалках

Ромка аватар

Quote:Аватар и прочие данные

[quote]Аватар и прочие данные важнее не разово вытаскивать, а иметь возможность синхронизировать, при каких-нить условиях[/quote]
Я думаю таким условием сделать авторизацию. То есть при каждой авторизации будут обновляться все данные кроме статуса. Обновление статуса будет отслеживаться постоянно.

Статус

Обновления статуса лучше делать по хрону, на хабре было обсуждение сего в купе с твитером.

Ромка аватар

Там фигня в том, что

Там фигня в том, что обращение к вконтактовскому АПИ идет через java-скрипт, пока, из PHP дергать его я не научился. Так что в любом случае инициировать процесс получения статуса может только залогиненый через вконтакт юзер.

Думаю сделать так: на hook_user повесить проверку, когда в последний раз синхронизировались данные с вконтактом если это делалось более определенного времени назад, то в тело страницы, будет добавляться java-скрипт, забирающий обновления и яаксом пишущий их в БД.

Ну и головняк они изобрели...

Ром, что-то нифика я не могу найти ссылок на то, что именно через js все таскается.
Ткни плиз носом...

На хабре видел реализацию через curl - как раз статья про синхронизацию статусов

Может таки нативно http://api.drupal.org/api/function/drupal_http_request/6 что-то можно?

проверка

хочу написать что-нибудь, чтобы проверить модуль и сказать автору спасибо.

Ромка аватар

Пожалуйста, жду от вас

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

Хмм

Кстати, у меня не получилось заставить его работать пока.
Не появляется кнопка.

Должно ли пройти время с момента регистрации приложения 'В Контакте' ?
Т.е. пройти проверку оно должно?

Указал ключ, секретный код, site url (http://www.example.com), base url (example.com).

Еще бажик: когда впервый раз зашел в настройку модуля, Site Url был указан как "http://http://www.example..." т.е. с лишними 'http://'

Ромка аватар

Вообще модуль в эти поля

Вообще модуль в эти поля никакие значения не должен прописывать...

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

Роли

Еще момент:
если на сайте несколько ролей, модуль присваивает к этой авторизации "минимальную, базовую" роль?
или как? у меня на сайте анонимы, к примеру, не имеют права оставлять комментарии.

что-то непонятное

Попробовал установить модуль заново и вспомнил, что при первом заупске (активации модуля) у меня возник белый экран с адресом "http://www.сайт.ru/admin/build/modules/list/confirm"

после обновления страницы, модуль как-бы активируется, но работать, походу, отказывается.

и так каждый раз (если удалить модуль и попробовать заново), белый экран при первой активации модуля.

Ромка аватар

А какая проблема была? И

А какая проблема была? И какое у нее решение? Может быть я смогу ее в самом модуле предотвратить? Или опишу в документации к модулю, чтобы другие пользователи знали как ее исправить.

Проблема была в том, что у

Проблема была в том, что у меня в настройках .html файлы обрабатывались особым образом, пришлось сделать специальное правило для /vk/xd_receiver.html :

  1. location /vk/xd_receiver.html {
  2. try_files $uri @drupal;
  3. }
  4.  
  5. location @drupal {
  6. index index.php;
  7. if (!-e $request_filename) {
  8. rewrite ^/(.*)$ /index.php?q=$1 last;
  9. }
  10. }

(Использовал для настройки nginx - http://github.com/yhager/nginx_drupal

Страницы