Авторизация через социальные сети или Немного о Loginza

Некоторое время назад задумал сделать один проект по соционике, но сильно мешала мысль "опять надо делать авторизацию, регистрацию, восстановление пароля и т.д.", тем более что проект был небольшим и эта часть получалась самой трудоемкой. Решил пойти другим путем: что если отказаться от собственной регистрации вообще, а использовать только авторизацию через социальные сети. Безуспешно попытавшись разобраться с авторизацией ВКонтакте (документация там просто ужасна), стал рассматривать другие варианты и наткнулся на сервис Loginza, который позволяет делать авторизацию через самые разные социальные Сети: не только ВКонтакте, Facebook и My.Mail.Ru, но и еще более десятка.

Стал разбираться в ее API, и оказалось, что все до предельного просто: регистрируемся на сайте Loginza, заходим в раздел "Мой виджет Loginza", там указываем адрес своего сайта и проходим подтверждение. Получаем идентификатор и секретный ключ. После этого подключаем на сайт widget Loginza — простой тег script c URL https://loginza.ru/api/widget, в параметре token_url которого указываем адрес на нашем сайте, куда пользователь попадет после авторизации. Нажав на widget, пользователь выбирает провайдера авторизации. После этого происходит редирект на указанный адрес, где через POST-запрос передается некий token. Далее нам предстоит сделать запрос к серверу уже из скрипта на серверной стороне (я использовал модуль cURL), чтобы по token и подписи (которая представляет собой MD5-хеш от token и секретного ключа) получить данные о пользователе. Данные приходят в формате JSON, остается только декодировать их, проверить на наличие ошибок и сохранить в сессию (а при необходимости — в базу данных). И все, авторизация пользователя готова!

Таким образом, вместо нескольких дней разработки получаем менее чем за час полностью работающую авторизацию! Вот пример кода:


<!DOCTYPE html>
<html>
<head>
<title>Экспериментируем с Loginza</title>
<script src="//loginza.ru/js/widget.js" type="text/javascript"></script>
<meta charset="utf-8" />
</head>

<body>
<a href="https://loginza.ru/api/widget?token_url=<?php echo urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);?>&providers_set=vkontakte,facebook,twitter" class="loginza">Войти через OpenID</a>
<?php

session_name('Loginza_Test');
if (isset($_REQUEST['Loginza_Test'])) session_start(); // открываем сессию в том случае, если пользователь уже авторизовался (см. http://new.xpro.su/php/php для объяснения почему нужна такая проверка)

if ($_SERVER['REQUEST_METHOD']=='POST') {
$id=42913; // здесь пишем ID сайта, выданный Loginza
$key='********************************'; // здесь пишем ключ, выданный Loginza
$token=$_POST['token']; // получаем Token из запроса
$sig=md5($token.$key); // цифровая подпись запроса
if (function_exists('curl_init') && $curl=curl_init()) { //
curl_setopt($curl, CURLOPT_URL, 'http://loginza.ru/api/authinfo?token='.$token.'&id='.$id.'&sig='.$sig);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_POST, false);
$json_data = curl_exec($curl);
curl_close($curl);
$user_data = json_decode($json_data,true);
if ($user_data && !isset($user_data['error_type'])) { // если в результате проверки не обнаружилось ошибок
session_start(); // создаем сессию пользователя, если авторизация успешна
$_SESSION['user']=$user_data; // запоминаем данные пользователя в сессию
// тут можно сделать сохранение полученных данных о пользователе в базу данных, если это нужно
}
else { // если возникла ошибка, выводим ее
echo 'Ошибка авторизации! ';
if (isset($user_data['error_message'])) echo $user_data['error_message'];
}
}
else echo 'Не найден модуль CURL или он работает некорректно!';
}
elseif (isset($_REQUEST['logout'])) { // для выхода пользователя
$_SESSION['user']=NULL;
session_destroy();
}

if (isset($_SESSION['user']['name'])) { // действие только для авторизованного пользователя
echo 'Мы тебя узнали, '.htmlspecialchars($_SESSION['user']['name']['first_name']).'!';
print_r($_SESSION['user']); // выведем все, что удалось о пользователе узнать
}
?>
</body>
</html>

Пожалуй, единственный недостаток такой авторизации — в том, что разные провайдеры авторизации предоставляют различный объем данных о пользователе. Например, ВКонтакте не предоставляет адрес EMail, Яндекс — данные о возрасте, и т.п.