- PVSM.RU - https://www.pvsm.ru -
Я очень давно хотел для UMI сделать скрип отличный от loginza, так как считаю, что он не совсем удачный, по ряду причин (чисто субъективных). Могу ошибаться, если так и есть не закидывайте камнями.
Был вдохновлен одной из статей на habrahabr, к сожалению статья была удалена. Во всяком случае, ссылку на всякий пожарный оставлю — этой статьей [1]. В этой статье было рассказано в общем как подключать HybridAuth к своему сайта, и созрел для реализации метода и написания своей статьи.
Постараюсь рассмотреть реализацию авторизацию на UMI.CMS через популярную библиотеку HybridAuth.
Авторизация для UMI.CMS будет реализована через провайдеров:
Статья по HybridAuth для UMI.CMS будет разделена на несколько статей:
1) Настройка полей пользователя
2) Установка и настройка HybridAuth
3) Установка скрипта HybridAuth + UMI.CMS
4) Корректировка шаблона
Для начала следует зайти в шаблоны данных (модуль) и найти там тип данных «Пользователь»:
[2]
Добавить новое поле «Аватар» и «ID пользователя из соц. сети»:
Настройка пользователей закончена.
Скачать библиотеку можно здесь [6] (это оригинальные файлы), а здесь [7] доп. провадеров. По этой [8] ссылке можно скачать с уже добавленным vk.com(предлагаю использовать этот архив).
Для начала нужно создать приложения для своего сайта. Я не буду расписывать процесс создания приложения, уверен, вы самостоятельно в этом разберетесь. Для того, чтобы Вы быстрее разобрались привожу ссылки на создания приложения:
Далее, нужно сконфигурировать HybridAuth. Для этого откройте _http://ваш_сайт/hybridauth/install.php и выберите нужные сервисы. Хочу обратить внимание на то, что ребята разработавшие hybridauth сразу привели ссылки на создание приложений.
После того, как Вы внесли все настройки и сохранили, должны увидеть что-то вроде этого:
Теперь нужно добавить нового провайдера.
Если Вы воспользовались оригинальными файлами из репозитория, то нужно установить провайдера для vk.com (если взяли готовый архив, то пропустите настройку vk.com). Следует перейти по этой [15] ссылке и скачать файл. Его нужно разместить в директории hybridauthHybridProviders. В файле hybridauthconfig.php добавить участок кода и вписать id и secret, который предоставить вконтакте.
"Vkontakte" => array (
"enabled" => true,
"keys" => array ( "id" => "", "secret" => "" )
),
Далее, нужно разместить в корне файл auth_with_social.php [16] со следующим содержанием:
session_start();
require_once('standalone.php');
$config = CURRENT_WORKING_DIR . '/hybridauth/config.php';
require CURRENT_WORKING_DIR . '/hybridauth/Hybrid/Auth.php';
$domain = cmsController::getInstance()->getCurrentDomain()->getHost(); // Получение домена
$users = cmsController::getInstance()->getModule("users"); // "Подключение" к модулю users
$data = cmsController::getInstance()->getModule("data"); // "Подключение" к модулю data
/*
* /auth_with_social.php?login_with=_fb
* /auth_with_social.php?login_with=_vk
* /auth_with_social.php?login_with=_in
* /auth_with_social.php?login_with=_gp
* /auth_with_social.php?login_with=_tw
* */
if( isset( $_GET["login_with"] ) ) {
$login_with = $_GET["login_with"];
try {
$hybridauth = new Hybrid_Auth($config);
$adapter = false;
switch ($login_with) {
case "_fb":
$adapter = $hybridauth->authenticate( "facebook" );
break;
case "_vk":
$adapter = $hybridauth->authenticate( "vkontakte" );
break;
case "_in":
$adapter = $hybridauth->authenticate( "linkedin" );
break;
case "_gp":
$adapter = $hybridauth->authenticate( "google" );
break;
case "_tw":
$adapter = $hybridauth->authenticate( "twitter" );
break;
}
// Если в параметр передана "чушь" выдаем ошибку
if(!$adapter) die( "<b>Ошибка про авторизации! Попробуйте еще раз.</b> ");
$profile = $adapter->getUserProfile();
// Если пользователь не залогинен - редирект
if( !isset( $profile ) ){
/* Редирект $profile случае запроса auth_with_social.php без параметров */
$domain = cmsController::getInstance()->getCurrentDomain()->getHost();
header ("Location: http://" . $domain);
// Если пользователь залогинен, продолжаем работу :)
} else {
echo "Отладочная информация";
echo "<pre>";
print_r($profile);
echo "</pre>";
$objectTypes = umiObjectTypesCollection::getInstance();
$objectTypeId = $objectTypes->getBaseType("users", "user");
$objectType = $objectTypes->getType($objectTypeId);
$provider = $login_with; // Провайдер через который авторизовался пользователь
$identifier = $profile->identifier;
$login = $profile->email;
$email = $profile->email;
if(iconv_strlen($login) == 0) {
$login = transliterate($profile->firstName);
$login .= $profile->identifier;
$email = $login . '@'. $domain;
}
$fname = $profile->firstName;
$lname = $profile->lastName;
$password = md5(generate_password(10));
$sel = new selector('objects');
$sel->types('object-type')->name('users', 'user');
$sel->where('e-mail')->equals($email);
$user = $sel->first;
if( $user instanceof iUmiObject ) {
permissionsCollection::getInstance()->loginAsUser($user);
session_commit();
header ("Location: http://" . $domain);
} else {
if(!preg_match("/.+@.+..+/", $email)) {
while(true) {
$email = $login.rand(1,100)."@".getServer('HTTP_HOST');
if($this->checkIsUniqueEmail($email)) {
break;
}
}
}
$object_id = umiObjectsCollection::getInstance()->addObject($login, $objectTypeId);
$object = umiObjectsCollection::getInstance()->getObject($object_id);
$object->setValue("login", $login);
$object->setValue("password", md5($password));
$object->setValue("e-mail", $email);
$object->setValue("fname", ($fname));
$object->setValue("lname", $lname);
$object->setValue("loginza", $provider);
$object->setValue("social_identifier", $identifier);
$object->setValue("register_date", time());
$object->setValue("is_activated", '1');
$object->setValue("activate_code", md5(uniqid(rand(), true)));
/* Создание аватара пользователя */
$user_pic = "./files/users_upload/social_avatars/";
$user_pic .= $identifier . $provider;
$png_pos = strpos($profile->photoURL , '.png');
$gif_pos = strpos($profile->photoURL , '.gif');
if ( $png_pos !== false )
$user_pic .= ".png";
elseif ( $gif_pos !== false )
$user_pic .= ".gif";
else
$user_pic .= ".jpeg";
// How to save facebook profile picture using php graph Api
// http://goo.gl/zgL3iR
// Сохранение изображения с заданного URL-адреса
// http://goo.gl/VHeXk1
$data = file_get_contents($profile->photoURL);
$file = fopen($user_pic, 'wb');
fputs($file, $data);
fclose($file);
if( file_exists("$user_pic") ) {
$oFile = new umiFile($user_pic);
if (!$oFile->getIsBroken()) {
$object->setValue("avatar", $oFile);
}
}
/* // Создание аватара пользователя */
$_SESSION['cms_login'] = $login;
$_SESSION['cms_pass'] = md5($password);
$_SESSION['user_id'] = $object_id;
session_commit();
$group_id = regedit::getInstance()->getVal("//modules/users/def_group");
$object->setValue("groups", Array($group_id));
$data_module = cmsController::getInstance()->getModule('data');
$data_module->saveEditedObject($object_id, true);
$object->commit();
header ("Location: http://" . $domain);
}
}
} catch( Exception $e ) {
/*$html = "Ошибка при авторизации. Информация об ошибки ниже: <br>";
$html .= "<b>" . $e->getMessage() . "</b>";
die( $html );*/
header ("Location: http://" . $domain . '/authorization/?error=' . $e->getMessage());
}
} else {
/* Редирект в случае запроса auth_with_social.php без параметров */
header ("Location: http://" . $domain);
}
/*
* Генератор пароля
* */
function generate_password($number) {
$arr = array('a','b','c','d','e','f',
'g','h','i','j','k','l',
'm','n','o','p','r','s',
't','u','v','x','y','z',
'A','B','C','D','E','F',
'G','H','I','J','K','L',
'M','N','O','P','R','S',
'T','U','V','X','Y','Z',
'1','2','3','4','5','6',
'7','8','9','0','-');
// Генерируем пароль
$pass = "";
for($i = 0; $i < $number; $i++)
{
// Вычисляем случайный индекс массива
$index = rand(0, count($arr) - 1);
$pass .= $arr[$index];
}
return $pass;
}
/*
* Транслит руского языка
* */
function transliterate($input) {
$gost = array(
"Є"=>"YE","І"=>"I","Ѓ"=>"G","і"=>"i","№"=>"-","є"=>"ye","ѓ"=>"g",
"А"=>"A","Б"=>"B","В"=>"V","Г"=>"G","Д"=>"D",
"Е"=>"E","Ё"=>"YO","Ж"=>"ZH",
"З"=>"Z","И"=>"I","Й"=>"J","К"=>"K","Л"=>"L",
"М"=>"M","Н"=>"N","О"=>"O","П"=>"P","Р"=>"R",
"С"=>"S","Т"=>"T","У"=>"U","Ф"=>"F","Х"=>"Kh",
"Ц"=>"C","Ч"=>"CH","Ш"=>"SH","Щ"=>"SHH","Ъ"=>"'",
"Ы"=>"Y","Ь"=>"","Э"=>"E","Ю"=>"YU","Я"=>"YA",
"а"=>"a","б"=>"b","в"=>"v","г"=>"g","д"=>"d",
"е"=>"e","ё"=>"yo","ж"=>"zh",
"з"=>"z","и"=>"i","й"=>"j","к"=>"k","л"=>"l",
"м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
"с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"kh",
"ц"=>"c","ч"=>"ch","ш"=>"sh","щ"=>"shh","ъ"=>"",
"ы"=>"y","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya",
" "=>"-","—"=>"-",","=>"-","!"=>"-","@"=>"-",
"#"=>"-","$"=>"","%"=>"","^"=>"","&"=>"","*"=>"",
"("=>"",")"=>"","+"=>"","="=>"",";"=>"",":"=>"",
"'"=>"","""=>"","~"=>"","`"=>"","?"=>"","/"=>"",
"\"=>"","["=>"","]"=>"","{"=>"","}"=>"","|"=>"", "."=>"-"
);
$string = strtr($input, $gost);
return strtolower($string);
}
Далее в файл .htaccess добавить строку:
###### SOCIAL #####
RewriteRule ^hybridauth/(.*)*$ hybridauth/index.php?%{QUERY_STRING} [L]
###### // SOCIAL #####
Далее нужно добавить в шаблон ссылки, для авторизации через соц. сети. Нужно взять вот этот код:
<ul class="b-social-links">
<li class="b-social-links__item">
<a href="/auth_with_social.php?login_with=_fb" class="fb" title="Войти используя Facebook">Войти используя Facebook</a>
</li>
<li class="b-social-links__item">
<a href="/auth_with_social.php?login_with=_vk" class="vk" title="Войти используя ВКонтакте">Войти используя ВКонтакте</a>
</li>
<li class="b-social-links__item">
<a href="/auth_with_social.php?login_with=_in" class="in" title="Войти используя LinkedIn">Войти используя LinkedIn</a>
</li>
<li class="b-social-links__item">
<a href="/auth_with_social.php?login_with=_gp" class="gp" title="Войти используя Google+">Войти используя Google+</a>
</li>
<li class="b-social-links__item">
<a href="/auth_with_social.php?login_with=_tw" class="tw" title="Войти используя Twitter">Войти используя Twitter</a>
</li>
</ul>
На этом с настройкой все.
Теперь хочу обратить внимание на то, если произошла ошибка при авторизации. Если такое произошло, то скрипт производит редирект на страницу /authorization/ с get параметром error.
Для того, чтобы показать пользователю ошибки, нужно создать страницу в структуре сайта и ее урл сделать /authorization/. Далее при помощи xslt отработать параметр error. TPL-шаблоназатор не рассматриваю.
Ссылки:
P.S. Если есть вопросы и непонятные моменты пишите комментарии.
P.S.S. Если Вы нашли ошибку, сообщите, я сразу исправлю. Старался побыстрее поделится опытом, может кому и пригодится.
Спасибо за внимание.
Автор: kibal4iw
Источник [19]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/cms/65333
Ссылки в тексте:
[1] этой статьей: http://habrahabr.ru/post/149187/
[2] Image: http://pontyk.com.ua/wp-content/uploads/2014/07/hybridauth-dlya-umi-cms-3.png
[3] Image: http://pontyk.com.ua/wp-content/uploads/2014/07/hybridauth-dlya-umi-cms-4.png
[4] Image: http://pontyk.com.ua/wp-content/uploads/2014/07/hybridauth-dlya-umi-cms-5.png
[5] Image: http://pontyk.com.ua/wp-content/uploads/2014/07/hybridauth-dlya-umi-cms-6.png
[6] здесь: http://hybridauth.sourceforge.net/index.html
[7] здесь: https://github.com/hybridauth/hybridauth/tree/master/additional-providers
[8] этой: http://pontyk.com.ua/wp-content/uploads/2014/07/hybridauth.zip
[9] Facebook: https://support.google.com/wildfire/answer/3467758?hl=ru&ref_topic=3473113
[10] Twitter: https://support.google.com/wildfire/answer/3467713?hl=ru&ref_topic=3473113
[11] Google+: https://support.google.com/wildfire/answer/3467714?hl=ru&ref_topic=3473113
[12] Вконтакте: https://vk.com/editapp?act=create
[13] Linkedin.com: https://www.linkedin.com/secure/developer
[14] Image: http://pontyk.com.ua/wp-content/uploads/2014/07/hybridauth-dlya-umi-cms-2.png
[15] этой: https://github.com/hybridauth/hybridauth/tree/master/additional-providers/hybridauth-vkontakte/Providers
[16] auth_with_social.php: http://pontyk.com.ua/wp-content/uploads/2014/07/auth_with_social-2.zip
[17] Страница загрузки библиотеки и плагинов: http://hybridauth.sourceforge.net/download.html
[18] Страница проекта на GitHub: https://github.com/hybridauth/hybridauth
[19] Источник: http://habrahabr.ru/post/230365/
Нажмите здесь для печати.