Подключение библиотеки HybridAuth в приложение Phalcon

Подключение библиотеки HybridAuth в приложение Phalcon

Сна­ча­ла инста­ля­ция биб­лио­те­ки вруч­ную через ска­чи­ва­ние паке­та https://​github​.com/​h​y​b​r​i​d​a​u​t​h​/​h​y​b​r​i​d​a​u​t​h​/​r​e​l​eases или через composer добав­ле­ние строк в composer.json:

{
    "require" : {
        "hybridauth/hybridauth" : "~3.0"
    }
}

и уста­нов­ка: composer install

Затем необ­хо­ди­ма настрой­ка биб­лио­те­ки на кон­крет­ных про­вай­де­ров, кото­рые нуж­но исполь­зо­вать. Ука­зы­ва­ем необ­хо­ди­мые дан­ные в фай­ле кон­фи­гу­ра­ции config/config.php:

'hybridauth' => [
        'providers' => [
            'Google' => [
                'enabled' => true,
                'keys'    => [
                    'id'     => 'Client ID',
                    'secret' => 'Secret Key'
                ],
            ],
            'Facebook' => [
                'enabled' => true,
                'keys'    => [
                    'id'     => 'Client ID',
                    'secret' => 'Secret Key'
                ],
            ],
            'Twitter' => [
                'enabled' => true,
                'keys'    => [
                    'key'    => 'Client ID',
                    'secret' => 'Secret Key'
                ],
            ],
        ],
        'debug_mode'   => true,
        'curl_options' => [
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_CAINFO         => dirname(__FILE__) . '/ca-bundle.crt', // путь к сертификату
        ],
        'http_client' => null,
        'callback' => 'https://example.com/path/to/this/script.php',
    ],

для полу­че­ния Client ID и Secret Key у каж­до­го про­вай­де­ра надо заре­ги­стри­ро­вать и настро­ить своё при­ло­же­ние. Поче­му-то этот про­цесс у всех оформ­лен мак­си­маль­но запу­тан­но и непо­нят­но, поэто­му луч­ше сна­ча­ла почи­тать как это сде­лать в каж­дом кон­крет­ном случае.

Даль­ше мож­но под­клю­чить биб­лио­те­ку через DI сер­вис как-то так:

use Phalcon\DI\FactoryDefault;
$di = new Phalcon\Di\FactoryDefault();
$di->set('hybridauth', function () use($config) {
    $hybridauth = new \Hybridauth\Hybridauth($this->config->hybridauth->toArray());
    return $hybridauth;
});

и потом исполь­зо­вать, к при­ме­ру, в кон­трол­ле­ре: $adapter = $this->hybridauth->authenticate("Facebook");.

В моём кон­крет­ном при­ме­ре, я не под­клю­чаю сер­вис, а исполь­зую пря­мой вызов биб­лио­те­ки в сво­ём кон­трол­ле­ре SocialController. Добав­ляю марш­рут роу­те­ру Phalcon\Mvc\Router

/**
* Routes for social actions
*/
$router->add('/social/{action:(login|connect|signup)}/{provider}', [
    'controller' => 'social',
    'action'     => 1,
    'provider'   => 2
])->setName("go-social");

то есть url для кон­трол­ле­ра SocialController с экшн loginAction и про­вай­де­ром Facebook будет выгля­деть как /social/login/facebook, в самом кон­трол­ле­ре (упро­щён­ная версия):

class SocialController extends Controller
{
/**
     * Action Starts a session via social login clicks
     *
     * @param $provider
     * @return \Phalcon\Http\Response|\Phalcon\Http\ResponseInterface|void
     * @throws ExceptionController
     */
    public function loginAction($provider)
    {
        try {            
            $SocialAuth = new Hybridauth\Hybridauth($this->config->hybridauth);

            // sign in
            $adapter = $SocialAuth->authenticate($provider);

            // request user profile
            $userProfile = $adapter->getUserProfile();

            // Check for SocialAccount in database
            $Social = SocialAuthModel::findFirst([
                'conditions' => 'identifier = :identifier: AND provider = :provider:',
                'bind' => [
                    'identifier' => $userProfile->identifier,
                    'provider' => $provider,
                ]
            ]);

            // If SocialAccount is not exist check for email
            if (!$Social) {
                // Try to find the user via email
                $User = Users::findFirst([
                    'conditions' => 'email = :email:',
                    'bind' => [
                        'email' => $userProfile->email,
                    ]
                ]);
                $Social = new SocialAuthModel();
            } else {
                $User = Users::findFirst($Social->usersId);
            }

            if (!$User)
                throw new SocialException("You must signup first");

            $Social->identifier = $userProfile->identifier;
            $Social->provider = $provider;
            $Social->accessToken = $accessToken;

            $User->social = $Social;

            if (!$User->save()) {
                throw new SocialException(implode("<br />", $User->getMessages()));
            }

            // raise Auth Exception if fail
            $this->auth->authUserById($Social->usersId);
        }
        /**
        * Catch Curl Errors
        *
        * This kind of error may happen when:
        *     - Internet or Networks issues.
        *     - Your server configuration is not setup correctly.
        * The full list of curl errors that may happen can be found at http://curl.haxx.se/libcurl/c/libcurl-errors.html
        */
        catch (\Hybridauth\Exception\HttpClientFailureException $e) {
            throw new SocialException ('Curl text error message : ' . $adapter->getHttpClient()->getResponseClientError());
        }
        /**
        * Catch API Requests Errors
        *
        * This usually happen when requesting a:
        *     - Wrong URI or a mal-formatted http request.
        *     - Protected resource without providing a valid access token.
        */
        catch (\Hybridauth\Exception\HttpRequestFailedException $e) {
            throw new SocialException ('Raw API Response: ' . $adapter->getHttpClient()->getResponseBody());
        } catch (\Hybridauth\Exception\RuntimeException $e) {
            throw new SocialException ('Runtime Response: ' . $e->getMessage());
        } catch (SocialException $e) {
            throw new SocialException($e->getMessage());
        }
    }
}

здесь сам про­цесс аутен­ти­фи­ка­ции зани­ма­ет толь­ко пер­вые 3 строч­ки, осталь­ное это уже реа­ли­за­ция кон­крет­ной зада­чи. Сна­ча­ла под­клю­че­ние биб­лио­те­ки $SocialAuth = new Hybridauth\Hybridauth($this->config->hybridauth);, затем аутен­ти­фи­ка­ция у кон­крет­но­го про­вай­де­ра $adapter = $SocialAuth->authenticate($provider);, и полу­че­ние инфор­ма­ции о поль­зо­ва­те­ле у про­вай­де­ра $userProfile = $adapter->getUserProfile(); в виде клас­са Hybridauth\User\Profile, опи­са­ние инфор­ма­ции кото­рая доступ­на для чте­ния о поль­зо­ва­те­ле в доку­мен­та­ции https://​hybridauth​.github​.io/​d​e​v​e​l​o​p​e​r​-​r​e​f​-​u​s​e​r​-​p​r​o​f​i​l​e​.html

Из заме­чен­ных осо­бен­но­стей мож­но отме­тить, что с локаль­ны­ми адре­са­ми сай­та (phalcon.local) может рабо­тать толь­ко twitter, осталь­ные тре­бу­ют реаль­но­го” адре­са сер­ве­ра. Что­бы полу­чить email поль­зо­ва­те­ля надо исполь­зо­вать настрой­ку scope в кон­фи­ге для HybridAuth или пере­да­вать его отдельно:

'Twitter' => [
                'enabled' => true,
                'keys'    => [
                    'key'    => 'Client ID',
                    'secret' => 'Secret Key'
                ],
                'scope' => 'email',
            ],

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

Поделиться / сохранить

Comments