Авторизация через соцсети это одна из самих частых задач с которыми сталкиваются разработчики развлекательных сайтов. Казалось бы там и делать нечего, ведь для каждого API существует PHP библиотека от самого вендора. Но что делать если надо подключить сразу несколько? Не хочется тянуть в проект кучу библиотек которые имплементируют один и тот же протокол OAuth, к тому же хотелось бы иметь какой-то единый интерфейс. PHPixie Social — маленькая библиотека с только одной зависимостью, которая позволяет легко работать сразу с Facebook, Twitter, Google и Вконтакте, а если вы используете PHPixie фреймворк то также сразу получаете авторизацию всего в несколько строчек кода.
Но сначала рассмотрим компонент сам по себе.
Конфигурация
<?php
$config = array(
// Имена провайдеров могут быть произвольными,
// но для простоты примера имя я взял с типа API
'facebook' => array(
'type' => 'facebook',
'appId' => '',
'appSecret' => '',
// опционально права которые запросить у пользователя,
'permissions' => array(),
// опционально версия API
'apiVersion' => '2.3'
),
'twitter' => array(
'type' => 'twitter',
// Twitter работает через OAuth 1.0a
// поэтому поля отличаются
'consumerKey' => '',
'consumerSecret' => ''
),
'google' => array(
'type' => 'google',
'appId' => '',
'appSecret' => '',
// опционально
'scope' => array(),
'apiVersion' => '2.3'
),
'vk' => array(
'type' => 'vk',
'appId' => '',
'appSecret' => '',
// опционально
'scope' => array(),
'apiVersion' => '2.3'
),
);
Инициализация
// та единственная зависимость
$slice = new \PHPixie\Slice();
$config = $slice->arrayData($config);
$social = new \PHPixie\Social($config);
Авторизация пользователя
Итак первое что нам надо сделать это запросить у пользователя авторизацию, для этого нам понадобится придумать какую-то ссылку куда API пришлет нам токен доступа. Тогда мы перенаправляем пользователя на страницу авторизации. Вот простой пример:
$callbackUrl = 'http://localhost.com/callback=1';
if(!isset($_GET['callback'])) {
//Если параметра нет, далаем редирект
$loginUrl = $social->get('facebook')->loginUrl($callbackUrl);
header('Location: '.$loginUrl);
} else {
// Если параметр есть, значит это к нам пришел ответ от API,
// с ним придет еще много параметров которые Social обработает сам.
// Заметьте, что значение $callbackUrl тут тоже нужно
$socialUser = $social->get('faceebook')->handleCallback($callbackUrl, $_GET);
if($socialUser === null) {
// Пользователь отклонил авторизацию
echo "You didn't authorize our app";
}else{
// Запрос к API от имени пользователя
var_dump($socialUser->get('me'));
}
}
Объект пользователя
$socialUser->id(); // ID пользователя в соцсети
// Дополнительная информация доступна после логина
$socialUser->loginData();
// GET Запрос
$socialUser->get('some/endpoint', $queryParams = array());
// POST Запрос
$socialUser->post('some/endpoint', $data = array(), $queryParams = array());
// Произвольный запрос
$socialUser->api('PUT', 'some/endpoint', $queryParams = array(), $data = array());
// Токен авторизации,
// его можно сериализировать и сохранить
// в сессии или в базе
$token = $social->token();
// Получить пользователя по токену
$socialUser = $social->get('facebook')->user($token);
// Кстати запросы можно делать сразу с токеном
$social->get('facebook')->get($token, 'some/endpoint', $queryParams = array());
$social->get('facebook')->post($token, 'some/endpoint', $data = array(), $queryParams = array());
$social->get('facebook')->api($token, 'PUT', 'some/endpoint', $queryParams = array(), $data = array());
Интеграция с фреймворком
В фреймворке по умолчанию доступен плагин к модулю авторизации, который обрабатывает логин пользователя и легко включается в его конфигурации. Те кто уже работает с фреймворком не найдут в этом ничего сложного, так что в этот раз вместо описания я оставлю ссылку на демо проект: https://github.com/phpixie/demo-socialauth
В нем пользователь сам выбирает через какую сеть авторизоваться. Если он зашел впервые, ему сразу-же создастся запись в табличке Users и логин запомнится через сессию. При последующем логине будет уже использоваться сущность с базы.
Чтобы попробовать Social, достаточно просто composer require phpixie/social, ну и как всегда, если у вас возникнуть какие-либо вопросы, обращайтесь сразу к нам в чат.
Комментарии (7)
jigpuzzled
11.06.2016 15:24В Social тоже есть абстрактная реализация Oauth, так что добавлять новые провайдеры также тривиально. Я изначально думал его прикрутить, но мне не очень понравился код плюс я хотел чтобы был стандартный сериализирумый клас токена, чтобы было легко сохранять их в базе и потом строить из них клас юзера. С hybridauth пришлось бы все равно это руками прописывать.
Radik_Wind
11.06.2016 22:27Так надо было подключить HybridAuth как зависимость и реализовать в своем компоненте все, что нужно для интеграции в PHPixie. Это бы позволило вам не изобретать свой велик, с экономить время и наверное самое главное получить интеграции с кучей сторонних сервисов без особого труда.
jigpuzzled
12.06.2016 01:11Для каждого сервиса все равно пришлось бы писать классы токена для сериализации. На самом деле велосипдность минимальная, так как в oauth нет ничего сложного совсем. Но зато получаете библиотеку построену с psr4 с более красивым кодом. А добавить сервисов плевое дело, только скажите какие вам надо. А писать провайдер для например Yahoo, который никому не надо просто для количества, смысла нет.
hanovruslan
14.06.2016 10:07Ну вот зачем так? Я про обоснование потенциального велосипеда. Вероятно, есть более существенные причины у вашего решения, но представленные в каментах имхо сомнительны.
Во-первых, разница между PSR-0 и PSR-4 минимальна, а если вы используете фичу optimized autoloader в композере, то вообще для работающего приложения не имеет значения (HybridAuth же работает, да?) как собственно и воообще следование PSR-0 или PSR-4
Во-вторых, кроме HybridAuth есть еще как минимум HWIOAuth. Он не без проблем, но в целом тоже работает. В нем, кстати, не надо писать классы токена для сериализации, да и вообще работа с токенами полностью на нём.
В-третьих, в том же HWIOauth есть почти все провайдеры которые требуются, а добавлять их на самом деле не так просто как кажется.
HWIOauth я указываю только как пример, с которым хорошо знаком.
А вообще вы же создаете собственную. комьюнити вокрут вашего фреймворка, если я не ошибаюсь, но с каждым новым стандартным решением (то, что решено коллегами из других комьюнити или вообще в мире PHP) у меня лично усиливается подозрение, что интегрировать ваше решение с решением не из ваших компонент, это задача нетривиальная. И, конечно, в такой ситуации лучше своё написать, чем подстраиваться под других.
jigpuzzled
14.06.2016 18:48В-третьих, в том же HWIOauth есть почти все провайдеры которые требуются, а добавлять их на самом деле не так просто как кажется.
я добавил 4 к пиксе вместе с абстрактным Oauth адаптером за 2 дня где-то.
А насчет интеграции с другими компонентами это совсем не так, на самом деле в самом фреймворке даже нет интеграции с Social, все далаеться через адаптеры типа: https://github.com/phpixie/auth-social и ничего не мешает сделать такой-же адаптер для HybridAuth
Кстати вот например OmniPay я переписывать не собираюсь, для него будет просто адаптер =)hanovruslan
15.06.2016 06:41Увы, но я не могу аргументировано ответить — нет достаточных знаний вашего продукта. Хотелось бы обратить внимание, что главным в моем предыдущем сообщении был последний абзац.
v-derckach
Из разного. Из того, что встречал я, HybridAuth — универсальная библиотека, поддерживает 60 провайдеров от фейсбука-вконтакта до гитхаба-инстаграма. Пряча внутри себя реализацию OAuth(2) и OpenID.