image
Авторизация через соцсети это одна из самих частых задач с которыми сталкиваются разработчики развлекательных сайтов. Казалось бы там и делать нечего, ведь для каждого 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)


  1. v-derckach
    11.06.2016 15:09
    +1

    Из разного. Из того, что встречал я, HybridAuth — универсальная библиотека, поддерживает 60 провайдеров от фейсбука-вконтакта до гитхаба-инстаграма. Пряча внутри себя реализацию OAuth(2) и OpenID.


  1. jigpuzzled
    11.06.2016 15:24

    В Social тоже есть абстрактная реализация Oauth, так что добавлять новые провайдеры также тривиально. Я изначально думал его прикрутить, но мне не очень понравился код плюс я хотел чтобы был стандартный сериализирумый клас токена, чтобы было легко сохранять их в базе и потом строить из них клас юзера. С hybridauth пришлось бы все равно это руками прописывать.


    1. Radik_Wind
      11.06.2016 22:27

      Так надо было подключить HybridAuth как зависимость и реализовать в своем компоненте все, что нужно для интеграции в PHPixie. Это бы позволило вам не изобретать свой велик, с экономить время и наверное самое главное получить интеграции с кучей сторонних сервисов без особого труда.


      1. jigpuzzled
        12.06.2016 01:11

        Для каждого сервиса все равно пришлось бы писать классы токена для сериализации. На самом деле велосипдность минимальная, так как в oauth нет ничего сложного совсем. Но зато получаете библиотеку построену с psr4 с более красивым кодом. А добавить сервисов плевое дело, только скажите какие вам надо. А писать провайдер для например Yahoo, который никому не надо просто для количества, смысла нет.


        1. hanovruslan
          14.06.2016 10:07

          Ну вот зачем так? Я про обоснование потенциального велосипеда. Вероятно, есть более существенные причины у вашего решения, но представленные в каментах имхо сомнительны.


          Во-первых, разница между PSR-0 и PSR-4 минимальна, а если вы используете фичу optimized autoloader в композере, то вообще для работающего приложения не имеет значения (HybridAuth же работает, да?) как собственно и воообще следование PSR-0 или PSR-4


          Во-вторых, кроме HybridAuth есть еще как минимум HWIOAuth. Он не без проблем, но в целом тоже работает. В нем, кстати, не надо писать классы токена для сериализации, да и вообще работа с токенами полностью на нём.


          В-третьих, в том же HWIOauth есть почти все провайдеры которые требуются, а добавлять их на самом деле не так просто как кажется.


          HWIOauth я указываю только как пример, с которым хорошо знаком.


          А вообще вы же создаете собственную. комьюнити вокрут вашего фреймворка, если я не ошибаюсь, но с каждым новым стандартным решением (то, что решено коллегами из других комьюнити или вообще в мире PHP) у меня лично усиливается подозрение, что интегрировать ваше решение с решением не из ваших компонент, это задача нетривиальная. И, конечно, в такой ситуации лучше своё написать, чем подстраиваться под других.


          1. jigpuzzled
            14.06.2016 18:48

            В-третьих, в том же HWIOauth есть почти все провайдеры которые требуются, а добавлять их на самом деле не так просто как кажется.


            я добавил 4 к пиксе вместе с абстрактным Oauth адаптером за 2 дня где-то.

            А насчет интеграции с другими компонентами это совсем не так, на самом деле в самом фреймворке даже нет интеграции с Social, все далаеться через адаптеры типа: https://github.com/phpixie/auth-social и ничего не мешает сделать такой-же адаптер для HybridAuth

            Кстати вот например OmniPay я переписывать не собираюсь, для него будет просто адаптер =)


            1. hanovruslan
              15.06.2016 06:41

              Увы, но я не могу аргументировано ответить — нет достаточных знаний вашего продукта. Хотелось бы обратить внимание, что главным в моем предыдущем сообщении был последний абзац.