Loginza – авторизация на сайте PHP
Последнее время стало очень модно использовать авторизацию на сайтах при помощи социальных сетей, учетные записи которых есть практически у каждого пользователя всемирной паутины. Это не только удобно, но и очень функционально, что дает массу информации о пользователе, который только зашел на ваш сайт. В связи с этим у многих появляется необходимость организовать связь между социальными сетями, базой данных и своим сайтом. Наиболее рациональным я вижу использование сервиса Loginza, нежели собирать по кусочкам с каждой социальной сети модули oAuth. В данной статье пойдет речь об организации авторизации на сайте при помощи сервиса Loginza.
Первое что нам нужно установить кнопки авторизации на сайт. Для этого необходимо встроить в нашу страницу небольшой HTML код. Например, если нужны абсолютно все сервисы авторизации, которые предоставляет Loginza, достаточно кода:
<script src="http://loginza.ru/js/widget.js" type="text/javascript"></script> <a href="https://loginza.ru/api/widget?token_url=http://loginza.test/login.php" class="loginza">Войти через OpenID</a>
Тогда диалог входа будет выглядеть следующим образом:

Если необходимо ограничить число сервисов для выбора, в примере будет использоваться именно этот вариант, то необходимо вставить код:
<script src="http://loginza.ru/js/widget.js" type="text/javascript"></script> <a href="https://loginza.ru/api/widget?token_url=http://loginza.test/login.php&provider=vkontakte&providers_set=vkontakte,facebook,twitter" class="loginza vkontakte_button"> </a> <a href="https://loginza.ru/api/widget?token_url=http://loginza.test/login.php&provider=facebook&providers_set=vkontakte,facebook,twitter" class="loginza facebook_button"> </a> <a href="https://loginza.ru/api/widget?token_url=http://loginza.test/login.php&provider=twitter&providers_set=vkontakte,facebook,twitter" class="loginza twitter_button"> </a>
Тогда диалог примет такой вид:

В исходном коде все очень просто, подключаем библиотеку Loginza, вставляем ссылки на кнопки, параметр которых в token_url содержит ссылку, на которую будет производиться переадресация после авторизации, а также список в виде параметров, кнопками каких сервисов необходимо ограничить авторизацию.
Затем нам необходимо создать таблицу в базе данных MySQL, в которой будет храниться информация о пользователе.
Структура таблицы базы данных будет выглядеть следующим образом:

С такой структурой у нас получается уникальная связка provider+uid которая не может повториться ни у одного пользователя и id – для учета пользователей внутри сайта (SQL файл прилагается в исходниках).
Теперь я бы хотел продемонстрировать наглядно, на примере, как можно организовать авторизацию с помощью Loginza.
Вот как выглядит исходный код главной страницы index.php:
<?php
session_start();
//кнопки для авторизации
function show_login_form(){
?>
<p><strong>Войти как пользователь</strong></p>
<script src="http://loginza.ru/js/widget.js" type="text/javascript"></script>
<a href="https://loginza.ru/api/widget?token_url=http://loginza.test/login.php&provider=vkontakte&providers_set=vkontakte,facebook,twitter" class="loginza vkontakte_button"> </a>
<a href="https://loginza.ru/api/widget?token_url=http://loginza.test/login.php&provider=facebook&providers_set=vkontakte,facebook,twitter" class="loginza facebook_button"> </a>
<a href="https://loginza.ru/api/widget?token_url=http://loginza.test/login.php&provider=twitter&providers_set=vkontakte,facebook,twitter" class="loginza twitter_button"> </a>
<?php
}
//отображение имени и кнопки для выхода
function show_menu(){
if($_SESSION['provider'] == 'http://vkontakte.ru/'){
$icon_class = 'vk_icon social_small_icon';
}
elseif($_SESSION['provider'] == 'http://www.facebook.com/'){
$icon_class = 'facebook_icon social_small_icon';
}
elseif($_SESSION['provider'] == 'http://twitter.com/'){
$icon_class = 'twitter_icon social_small_icon';
}
echo '<div class="'.$icon_class.'"></div>'.$_SESSION['firstname'] . ' ' . $_SESSION['lastname'];
echo '<div><a href="/exit.php">Выйти</a></div>';
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" media="screen" type="text/css" href="style.css" />
<title>Авторизация при помощи Loginza - sanchiz.net</title>
</head>
<body>
<?php
if(!isset($_SESSION['id'])) {
show_login_form();
}
else{
show_menu();
}
?>
</body>
</html>
Тут все просто, 2 функции, одна для показа кнопок для авторизации:

вторая для показа информации, если пользователь успешно прошел авторизацию:
![]()
Следующая часть модуля, она же самая функциональная это файл login.php:
<?php
//подключение к базе данных
$db = mysql_pconnect('localhost', 'admin', '111111', 128);
mysql_select_db('loginza_test');
//проверка получения токена
if (!isset($_POST['token'])) {
$error = 'Ошибка получения токена.';
}
//отправляем запрос на получение данных пользователя
elseif (false === ($authData = file_get_contents('http://loginza.ru/api/authinfo?token='.$_POST['token']))) {
$error = 'Ошибка получения данных.';
}
//если произошла ошибка
if (isset($error)) {
echo '<p>'.$error.'</p>';
}
else {
//декодируем данные о пользователе из формата JSON
$user = json_decode($authData);
//var_dump($user);
//если провайдер Вконтакте
if($user->provider == 'http://vkontakte.ru/'){
$uid = $user->uid;
$provider = $user->provider;
$firstname = $user->name->first_name;
$lastname = $user->name->last_name;
$identity = $user->identity;
}
//если провайдер Facebook
elseif($user->provider == 'http://www.facebook.com/'){
$uid = $user->uid;
$provider = $user->provider;
$firstname = $user->name->first_name;
$lastname = $user->name->last_name;
$email = $user->email;
$identity = $user->identity;
}
//Если провайдер Twitter
elseif($user->provider == 'http://twitter.com/'){
$uid = $user->uid;
$provider = $user->provider;
$firstname = $user->name->full_name;
$identity = $user->identity;
}
else{
echo '<p>Неизвестный провайдер.</p>';
}
if($uid && $provider){
$sql = 'SELECT * FROM users WHERE provider = "'.$provider.'" AND uid = "'.$uid.'"';
$result = mysql_query($sql);
session_start();
//если такого пользователя нету в базе данных заносим информацию в базу
if((mysql_num_rows($result)) == 0){
$sql = 'INSERT INTO users (uid, provider, identity, firstname, lastname, email) VALUES ("'.$uid.'", "'.$provider.'", "'.$identity.'", "'.$firstname.'", "'.$lastname.'", "'.$email.'")';
mysql_query($sql);
$user_id = mysql_insert_id();
$_SESSION['id'] = $user_id;
$_SESSION['provider'] = $provider;
$_SESSION['uid'] = $uid;
$_SESSION['firstname'] = $firstname;
$_SESSION['lastname'] = $lastname;
}
//если пользователь уже существует то присваиваем ему информацию из базы
else{
$user_row = mysql_fetch_assoc($result);
session_start();
$_SESSION['id'] = $user_row['id'];
$_SESSION['provider'] = $user_row['provider'];
$_SESSION['uid'] = $user_row['uid'];
$_SESSION['firstname'] = $user_row['firstname'];
$_SESSION['lastname'] = $user_row['lastname'];
}
//редирект на главную страницу
Header('Location: /');
}
}
?>
В нем сначала выполняется соединение с базы данных, далее проверка токенa отданного Loginza. Если токен получен, то отправляем запрос на получение данных пользователя. Когда данные получены, мы декодируем их из JSON формата функцией json_decode. Конструкция которая выполняет присвоения данных в зависимости от провайдера смотрится довольно громоздко, но тут уж ничего не поделаешь, все сервисы по-разному отдают информацию, поэтому приходится учитывать каждый случай. Следующее что мы делаем это запрос к базе данных, который выбирает пользователя с uid и provider полученного от Loginza. Если такой пользователь уже существует то мы просто присваиваем переменной сессии данные из базы. Если такого пользователя не существует, то мы заносим полученную информацию в базу данных и после чего следует переадресация на нужную нам страницу, где мы уже увидим ссылку на выход из учетной записи и иконку социальной сети с именем, полученным от сервиса.
Ну и последнее это файл exit.php, с помощью которого можно выполнить выход из учетной записи:
<?php
session_start();
session_unset();
session_destroy();
header("Content-type: text/html");
header('Location:/');
?>
Тут все очень просто, уничтожаем сессию и переадресовываем пользователя на главную страницу.
Вот так легко можно реализовать авторизацию при помощи социальных сетей. Возможно, некоторые моменты реализации я упустил, но это лишь доказывает всю мощь свободной авторизации при помощи oAuth.
Здесь небыли рассмотрены мелкие нюансы и методы построения модуля, а также средства безопасности и защиты, но это можно без напряга доработать.
Владимир
13:05 25.01.2013Статья отличная, очень помогла и опыта набрался)))
Сайт супер, много полезных статей.