Каждый второй сайт сегодня предлагает войти через соцсети. Это удобно пользователям и выгодно вам — меньше барьеров, больше конверсий. Но если вы работаете с Yii2, то наверняка задумывались: как подключить ВКонтакте, Facebook или Google без лишних танцев с бубном? В этой статье я покажу, что это проще, чем кажется. Вы узнаете, как настроить авторизацию через популярные соцсети, какие подводные камни бывают и как их обойти. Поехали!

Digital-студия WNDER

Что нам понадобится для интеграции

Прежде чем писать код, давайте разберемся, что вообще нужно для подключения соцсетей к Yii2. В основе всего лежит расширение yii2-auth от разработчиков Yii, которое поддерживает десятки провайдеров: от ВКонтакте до GitHub. Оно берет на себя всю рутину — обмен токенами, получение профиля, обработку ошибок.

Вам понадобится:

  • Сайт на Yii2 (базовая или продвинутая версия — не важно).
  • Composer для установки расширения.
  • Зарегистрированные приложения в соцсетях (ключи API).
  • Немного терпения и чашка кофе.

Установка расширения и настройка базы

Установка проходит через Composer — просто выполните команду в корне проекта:

composer require yiisoft/yii2-auth

После установки нужно создать таблицу для хранения учетных записей соцсетей. В расширении уже есть готовая миграция. Запускаем:

php yii migrate --migrationPath=@yii/auth/migrations

Эта команда создаст таблицу auth, где будут храниться данные о привязке пользователей к соцсетям. Теперь настроим компонент в конфигурационном файле config/web.php:

'components' => [
    'authClientCollection' => [
        'class' => 'yii\auth\Collection',
        'clients' => [
            'vkontakte' => [
                'class' => 'yii\auth\clients\VKontakte',
                'clientId' => 'ВАШ_ID_ПРИЛОЖЕНИЯ',
                'clientSecret' => 'ВАШ_СЕКРЕТНЫЙ_КЛЮЧ',
            ],
            'facebook' => [
                'class' => 'yii\auth\clients\Facebook',
                'clientId' => 'ВАШ_ID_ПРИЛОЖЕНИЯ_FACEBOOK',
                'clientSecret' => 'ВАШ_СЕКРЕТНЫЙ_КЛЮЧ_FACEBOOK',
            ],
            'google' => [
                'class' => 'yii\auth\clients\Google',
                'clientId' => 'ВАШ_ИДЕНТИФИКАТОР_GOOGLE',
                'clientSecret' => 'ВАШ_СЕКРЕТ_GOOGLE',
            ],
        ],
    ],
],

Как видите, для каждого провайдера — свой класс и свои ключи. Где взять ключи? В настройках приложения каждой соцсети. Обычно нужно создать приложение, указать адрес сайта и получить пару ID + секрет. Для локальной разработки подойдет http://localhost, но учтите — некоторые соцсети не разрешают использовать localhost, тогда придется прописать в hosts файле что-то вроде mysite.local.

Создание контроллера для обработки авторизации

Теперь создадим контроллер, который будет обрабатывать запросы от соцсетей. Назовем его AuthController. В нем будет два действия: перенаправление на соцсеть и обработка ответа.

Вот пример кода контроллера:

<?php

namespace app\controllers;

use Yii;
use yii\auth\AuthAction;
use yii\auth\ClientInterface;
use yii\web\Controller;
use app\models\User;
use app\models\Auth;

class AuthController extends Controller
{
    public function actions()
    {
        return [
            'index' => [
                'class' => AuthAction::class,
                'successCallback' => [$this, 'onAuthSuccess'],
            ],
        ];
    }

    public function onAuthSuccess(ClientInterface $client)
    {
        $attributes = $client->getUserAttributes();
        $auth = Auth::find()->where([
            'source' => $client->getId(),
            'source_id' => $attributes['id'],
        ])->one();

        if ($auth) {
            // Пользователь уже привязан — просто логиним
            Yii::$app->user->login($auth->user);
        } else {
            // Проверяем, есть ли пользователь с таким email
            $email = isset($attributes['email']) ? $attributes['email'] : null;
            $user = $email ? User::find()->where(['email' => $email])->one() : null;

            if (!$user) {
                // Создаем нового пользователя
                $user = new User();
                $user->email = $email;
                $user->password = Yii::$app->security->generateRandomString(16);
                $user->save();
            }

            // Сохраняем привязку
            $auth = new Auth();
            $auth->user_id = $user->id;
            $auth->source = $client->getId();
            $auth->source_id = (string)$attributes['id'];
            $auth->save();

            Yii::$app->user->login($user);
        }
    }
}

Что здесь происходит? Мы получаем атрибуты профиля от соцсети (ID, email, имя). Затем ищем в таблице auth запись с таким источником и ID. Если находим — просто логиним пользователя. Если нет — ищем пользователя по email, а если его нет — создаем нового с случайным паролем (он ему не понадобится, ведь вход будет только через соцсеть). И в конце сохраняем привязку и логиним.

Настройка маршрутов и виджетов

Теперь нужно добавить правило в config/web.php, чтобы URL для авторизации был красивым:

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
        'auth' => 'auth/index',
    ],
],

А в представлении (например, на странице входа) выводим виджеты для авторизации. Yii2 предоставляет готовый виджет AuthChoice, который сам генерирует ссылки на все подключенные соцсети. Вот как это выглядит:

<?php
use yii\auth\widgets\AuthChoice;
?>

<div class="social-auth">
    <p>Войти через соцсети:</p>
    <?= AuthChoice::widget([
        'baseAuthUrl' => ['auth/index'],
        'popupMode' => true,
    ]) ?>
</div>

Виджет автоматически отобразит кнопки всех провайдеров, которые вы настроили в authClientCollection. Если хотите изменить внешний вид кнопок, можно передать свой шаблон или стилизовать через CSS.

Обработка ошибок и дополнительные настройки

Иногда пользователь отменяет авторизацию в соцсети, или токен протухает. Нужно корректно обрабатывать такие ситуации. В AuthAction можно задать обработчик ошибки через параметр errorCallback. Добавим его в наш контроллер:

public function actions()
{
    return [
        'index' => [
            'class' => AuthAction::class,
            'successCallback' => [$this, 'onAuthSuccess'],
            'errorCallback' => function ($error) {
                Yii::$app->session->setFlash('error', 'Не удалось авторизоваться через соцсеть: ' . $error->getMessage());
                return Yii::$app->response->redirect(['site/login']);
            },
        ],
    ];
}

Еще один нюанс — получение email от некоторых соцсетей. Например, ВКонтакте требует запрос права на email отдельно. В настройках приложения VK нужно включить доступ к email и указать права email. В коде клиента это можно добавить через свойство scope:

'vkontakte' => [
    'class' => 'yii\auth\clients\VKontakte',
    'clientId' => 'ВАШ_ID',
    'clientSecret' => 'ВАШ_СЕКРЕТ',
    'scope' => 'email',
],

Аналогично для Facebook — там нужно указать права email и public_profile.

Правило: Всегда проверяйте, какие данные о пользователе вы получаете от соцсети. Не полагайтесь на то, что email будет всегда. Иногда его нет — тогда предлагайте пользователю ввести его вручную после регистрации.

Таблица популярных провайдеров и их особенностей

Разные соцсети ведут себя по-разному. Вот краткая таблица, которая поможет вам не наступить на грабли:

Провайдер Класс в Yii2 Особенности
ВКонтакте VKontakte Требует указать права на email в настройках приложения. Возвращает ID пользователя как число.
Facebook Facebook Нужны права email, public_profile. Иногда возвращает нестабильный ID, лучше использовать поле id.
Google Google Всегда возвращает email и подтвержденный статус. Хорошо документирован.
GitHub GitHub Email может быть скрыт, если пользователь не сделал его публичным.

Как обновить данные пользователя из соцсети

Когда пользователь уже вошел через соцсеть, его данные могут меняться (например, имя или аватар). Хорошая практика — обновлять профиль при каждом входе. Добавим в метод onAuthSuccess обновление данных:

if ($auth) {
    $user = $auth->user;
    // Обновляем имя, если оно изменилось
    if (isset($attributes['name']) && $user->username !== $attributes['name']) {
        $user->username = $attributes['name'];
        $user->save();
    }
    Yii::$app->user->login($user);
}

Только не забудьте проверить, что поле username не занято другим пользователем.

Виджет для отображения кнопок с кастомизацией

Стандартный виджет AuthChoice выводит кнопки как ссылки с иконками. Но иногда нужно изменить их внешний вид, например, добавить свои CSS-классы. Это делается через параметр options:

<?= AuthChoice::widget([
    'baseAuthUrl' => ['auth/index'],
    'popupMode' => false,
    'options' => ['class' => 'my-social-buttons'],
]) ?>

А в CSS уже стилизуете под свой дизайн. Если нужно вывести кнопки вручную, можно перебрать клиентов через Yii::$app->authClientCollection->getClients() и создать свои ссылки.

Тестирование и отладка

Перед запуском обязательно протестируйте каждый провайдер. Для этого нужно создать тестовые приложения в соцсетях с адресом вашего локального сайта. Имейте в виду, что некоторые соцсети (например, Facebook) требуют HTTPS, поэтому для локального тестирования придется настроить SSL-сертификат или использовать туннель типа ngrok.

Полезный совет: включите логирование запросов в Yii2, чтобы видеть, какие данные приходят от соцсети. В конфигурации добавьте:

'log' => [
    'targets' => [
        [
            'class' => 'yii\log\FileTarget',
            'levels' => ['error', 'warning'],
            'logFile' => '@runtime/logs/auth.log',
        ],
    ],
],

Так вы быстро найдете, почему не приходит email или где возникает ошибка.

Лайфхак: Для разработки не обязательно иметь реальные ключи соцсетей. Можно использовать тестовые режимы, которые предоставляют Facebook и Google. Они позволяют имитировать профили пользователей и проверять логику без риска для боевых аккаунтов.

Что в итоге

Интеграция с соцсетями в Yii2 — это не ракетостроение. С расширением yii2-auth вы подключаете любые соцсети за пару часов. Главное — правильно настроить приложения в самих соцсетях, указать нужные права и не забыть про обработку ошибок. В результате пользователи смогут входить в один клик, а вы получите меньше отказов от регистрации.

Попробуйте, и у вас точно получится. Если что-то пойдет не так — загляните в документацию расширения или в исходники, там все подробно расписано. Удачи в разработке!

Студия WNDER