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Статья отличная, очень помогла и опыта набрался)))
Сайт супер, много полезных статей.