Pull to refresh

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

Reading time 4 min
Views 48K
На хабре и других ресурсах есть туториалы, однако в каждом упущен какой-нибудь незначительный момент, вопросы по которому можно видеть на различных форумах. Так как недавно столкнулся с задачей подружить один сайт с Контактиком и Майл.ру, то решил, пока свежа память, сделать свое небольшое руководство с блэкджеком так сказать, используя родные виджеты этих социальных сетей.
Итак, начнем с ВКонтакте. Заходим на страницу подключения сайта, в дальнейшем настройки подключенного сайта будут доступны вам на странице управления приложениями, там мы узнаем ID приложения и секретный ключ, который естественно раскрывать никому нельзя.
На странице, на которой предполагается кнопочка «Войти через ВКонтакте» требуется добавить в head страницы
<script type="text/javascript" src="http://userapi.com/js/api/openapi.js?34"></script>

И инициализировать приложение:
VK.init({apiId: __APP_ID___});

Теперь нужно показать пользователю кнопку через вызов виджета. В качестве параметров Auth принимает id элемента, в который нужно отобразить виджет, ширину и адрес страницы, куда мы будем перенаправлены после попытки доступа.
      <div id="vk_auth"></div>
      <script type="text/javascript">
      VK.Widgets.Auth("vk_auth", {width: "300px", authUrl: '/vklogin.php?'});
      </script>


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



После щелчка на «Войти через ВКонтакте» пользователя кидает на страницу вида 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- и запретить пользователям из социальной сети менять себе пароль и, опционально, аватарку с отображаемым именем. Для сайтов, в которых критично использование электронной почты зарегистрированных пользователей необходимо будет также ознакомить ваш движок с тем фактом, что у этих пользователей нет электронной почты.
Опционально можно возле каждого вывода имени пользователя на сайте отдельно выделять, что он авторизовался через социальную сеть:

Если уровень и тематика статьи интересна хабрапользоватям, то я продолжу с майл.ру, facebook и твиттером.
Вторая часть. Mail.ru
Tags:
Hubs:
+89
Comments 45
Comments Comments 45

Articles