Привет, друзья. Хочу сегодня поделится своим взглядом на то, как можно сделать простую и эффективную авторизацию/регистрацию пользователей через любую социальную сеть, используя плагин Ulogin. Почему через этот плагин? Потому что он может избавить разработчика от кучи головной боли, которая возникнет при синхронизации с каждой социальной сетью в отдельности. Плюс вы сможете получить данные из плагина в едином красивом формате.
Я исхожу из того, что читатель разбирается во фреймворке Laravel 5.3 Поэтому я не буду разжевывать простые вещи. Итак, с чего начать? Для начала нам нужно на странице регистрации и авторизации подключить JS плагин. Лично я делаю это через создание отдельного шаблона auth/social.blade.php В который помещаю следующий простой код:
{{-- Social buttons--}}
<div class="text-center margin-bottom-20" id="uLogin"
data-ulogin="display=panel;theme=flat;fields=first_name,last_name,email,nickname,photo,country;
providers=facebook,vkontakte,odnoklassniki,mailru;hidden=other;
redirect_uri={{ urlencode('http://' . $_SERVER['HTTP_HOST']) }}/ulogin;mobilebuttons=0;">
</div>
@section('js')
<script src="//ulogin.ru/js/ulogin.js"></script>
@endsection
Немного объяснений к коду. urlencode используем для кодирования строки к нормальному для передачи по http виду. На redirect_uri будет приходить ответ от сервера Ulogin со статусами и данными. В поле fields мы указываем, какие данные нам нужно получить из социальной сети. В конце шаблона я подключаю сам плагин. Обратите внимание, что здесь происходит вставка кода в блок 'js', который должен быть прописан в главном шаблоне: yield('js')
Да, один момент. Если вы работаете по SSL, то вместо 'http://' указывайте 'https://'. Тогда не будет предупреждения о небезопасной передаче данных.
Когда шаблон готов, то мы его просто подключаем на странице регистрации и залогинивания в том месте, где нам нужно, просто вставив в шаблоне одну строчку: include('auth.social')
Все, теперь на странице регистрации появится симпатичный виджет с выбором социальных сетей. При клике на кнопку социальной сети, откроется новое окно для авторизации в конкретной социальной сети (если вы не авторизованы, конечно).
Теперь нам нужно написать бэкенд часть. А именно создать контроллер и роут. Роут будет получать ответ от сервера Ulogin и передавать его в наш контроллер.
Создаем контроллер с названием UloginController.php и прописываем в нем публичный метод login в который передаем запрос.
Создаем роут: Route::post('ulogin', 'UloginController@login');
Есть еще один нюанс! В Laravel есть защита от CSRF атак. А значит, передача данных с другого сервера не будет иметь токена безопасности и случится ошибка безопасности. Для того, чтобы это пофиксить, необходимо в посреднике (middleware) VerifyCsrfToken.php прописать исключение для нашего роута (пути): protected $except = ['ulogin'];
Теперь, когда сервер вернет ответ на '/ulogin', токен безопасности будет проигнорирован и ошибки не произойдет.
Теперь напишем сам контроллер:
<?php
/**
* Ulogin.ru auto registration or login.
*/
namespace AppHttpControllers;
use AppUser;
use Auth;
use Hash;
use IlluminateHttpRequest;
use Redirect;
class UloginController extends Controller
{
// Login user through social network.
public function login(Request $request)
{
// Get information about user.
$data = file_get_contents('http://ulogin.ru/token.php?token=' . $_POST['token'] . '&host=' . $_SERVER['HTTP_HOST']);
$user = json_decode($data, TRUE);
$network = $user['network'];
// Find user in DB.
$userData = User::where('email', $user['email'])->first();
// Check exist user.
if (isset($userData->id)) {
// Check user status.
if ($userData->status) {
// Make login user.
Auth::loginUsingId($userData->id, TRUE);
}
// Wrong status.
else {
Session::flash('flash_message_error', trans('interface.AccountNotActive'));
}
return Redirect::back();
}
// Make registration new user.
else {
// Create new user in DB.
$newUser = User::create([
'nik' => $user['nickname'],
'name' => $user['first_name'] . ' ' . $user['last_name'],
'avatar' => $user['photo'],
'country' => $user['country'],
'email' => $user['email'],
'password' => Hash::make(str_random(8)),
'role' => 'user',
'status' => TRUE,
'ip' => $request->ip()
]);
// Make login user.
Auth::loginUsingId($newUser->id, TRUE);
Session::flash('flash_message', trans('interface.ActivatedSuccess'));
return Redirect::back();
}
}
}
Как видно из кода, мы вначале проверяем, есть ли в нашей базе пользователь с таким email адресом. Если есть, то мы его сразу залогиниваем. Если нет, то мы вначале создаем пользователя в базе, а потом залогиниваем. Вероятность того, что кто-то создаст аккаунт в социальной сети с email адресом того, кто на вашем сайте уже зарегистрирован, для того, чтобы войти в чужой аккаунт, практически сведена к нулю, так как социальные сети требуют проверки указанного адреса.
Какие поля в базе данных видно из кода. Для вывода текстового сообщения я использую функцию перевода trans(), что позволяет мне использовать любые языки на сайте.
Вот и все. Просто, эффективно и очень гибко. В следующий раз, если будет время, я напишу о том, как можно автоматически залогинить/зарегистрировать пользователя, когда гость ставит лайк посту или жмет на кнопку создания комментария на вашем сайте. Там все посложнее, но тоже гибко и эффективно.
Автор: Kirill_Dan