Чат PHP-разработчиков
Авторизация в Symfony через социальные сети. Часть 1: авторизация через Google

Авторизация в Symfony через социальные сети. Часть 1: авторизация через Google

Сегодня многие общественные ресурсы заменяют собственную регистрацию на сайте на авторизацию через социальные сети. Причина? Во-первых, это удобно для пользователей. Во-вторых, вы все равно получите от пользователя достаточно информации, которую можете использовать: электронный адрес, имя, его никнейм, фотографию и много чего еще. Почти все то же самое мы можем требовать от пользователя при обычной регистрации, так почему бы не облегчить жизнь ему и себе?

Самый популярный и часто используемый протокол для такой авторизации - OAuth. Поскольку наше приложение является клиентом, мы должны сделать следующее:

  1. Редиректим пользователя на страницу авторизации (Google, Github, Yandex, Mail, etc);
  2. Там сервис (опять же, Google, Github и другие) запрашивают у пользователя подтверждения о выдаче прав нашему приложению;
  3. Получаем access_token, а вместе с ним доступ к тем ресурсам, которые мы запросили;
  4. Редиректим обратно на наше приложение.

Конечно, не забудем сохранить данные, которые к нам пришли, по которым мы и авторизуем пользователя, а также получим возможность установить ему фотографию, если получим, и имя.

Начало

Чтобы начать использовать OAuth, нужно зарегистрировать свое приложение в Google. Сделать это можно по следующей ссылке: https://console.developers.google.com/apis. Там вы должны выбрать пункт меню на боковой панели "Учетные данные", нажать "Создать учетные данные", выбрать из выпадающего списка "Идентификатор клиента OAuth" и выбрать чекбокс "Веб-приложение". После всего этого вы должны увидеть следующее:

Здесь вы должны указать название вашего приложения, redirect_uri и callback_uri. В первом поле указываете следующее: http://127.0.0.1:8000 (или просто копируете ваш урл), в callback_uri - http://127.0.0.1:8000/google/auth.

Далее нажмите "Создать". Вы получите clientId и client secret. Эти ключи нужны для идентификации подлинности вашего приложения. Сохраните их, скоро я покажу, как их использовать. Мы не будем с нуля писать авторизацию, вместо этого мы скачаем бандл, который уже умеет работать со множеством сервисов. Выполните в терминале в корне проекта следующую команду:

Код доступен только после покупки курса по фреймворку Symfony 4.

Также скачаем следующий пакет:

Код доступен только после покупки курса по фреймворку Symfony 4.

После установки бандла у вас появится конфигурационный файл knpu_oauth2_client.yaml в папке config/packages. Через него вы будете настраивать ваши client_id, client_secret, версию API, роут для редиректа и многое другое. Для авторизации через Google сделаем следующие настройки:

Код доступен только после покупки курса по фреймворку Symfony 4.

Теперь данные, которые вы сохранили, нужно сохранить в .env файл по следующим именам:

Код доступен только после покупки курса по фреймворку Symfony 4.

Создание авторизации

Если вы хотите оставить возможность пользователю проходить обычную регистрацию, тогда нам нужно несколько изменить нашу сущность, которую мы создали ранее:

Код доступен только после покупки курса по фреймворку Symfony 4.

Как видите, у нас нет сеттеров. Вместо этого мы сделали 2 именованных конструктора - для запроса на авторизацию от Google и Github. Во-первых, это удобно тем, что мы никогда не забудем передать нужные нам параметры, а во-вторых - сохранение некоторых свойств можно инкапсулировать в конструкторе (как, например, сохранение соц. сети, через которую вошел пользователь - oauthType).

Чтобы реализовать кастомную авторизацию через социальные сети, нам нужно или имплементировать AuthenticatorInterface, или отнаследоваться от AbstractGuardAuthenticator. Однако поскольку мы установили бандл oauth2-client-bundle, нам нужно отнаследоваться от него (он все равно так же наследуется от AbstractGuardAuthenticator). Вот как он будет выглядеть:

Код доступен только после покупки курса по фреймворку Symfony 4.

Итак, что мы здесь видим. Метод start() вызывается, когда пользователю требуется авторизация при запросе к запрещенным ресурсам. В данном случае он редиректит на страницу с логином, где пользователь сможет выбрать, как ему авторизоваться. Выполнение нашего класса аутентификации продолжается, только если метод supports() возвращает true. Другими словами, если мы попали на наш роут. Метод getCredentials() возвращает в данном случае access_token, по которому мы определяем права пользователя. Теперь мы подошли к самому важному методу - getUser(). Разберем код поэтапно:

  1. Достаем пользователя по access_token, который вернул метод getCredentials().
Код доступен только после покупки курса по фреймворку Symfony 4.
  1. Достаем его client_id.
Код доступен только после покупки курса по фреймворку Symfony 4.
  1. Проверяем, существует ли такой пользователь в базе. Если да, то пользователь уже авторизовывался через Google и можно его вернуть из базы.
Код доступен только после покупки курса по фреймворку Symfony 4.
  1. Если нет, продолжаем выполнение кода дальше и проверяем, есть ли пользователь с таким email в базе:
Код доступен только после покупки курса по фреймворку Symfony 4.
  1. Если пользователь есть, то, скорее всего, она был зарегистрирован через обычную форму, тогда просто сохраняем его client_id на будущее:
Код доступен только после покупки курса по фреймворку Symfony 4.
  1. Если же пользователя нет и по email, создаем его, сохраняем и возвращаем:
Код доступен только после покупки курса по фреймворку Symfony 4.

Остальные методы должны быть понятны по их названиям. Теперь напишем наш UserProvider:

Код доступен только после покупки курса по фреймворку Symfony 4.

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

Добавим в наш UserRepository следующий класс:

Код доступен только после покупки курса по фреймворку Symfony 4.

Осталось написать контроллер и сконфигурировать файл config/packages/security.yaml. Начнем с первого:

Код доступен только после покупки курса по фреймворку Symfony 4.

Метод redirectToGoogleConnect() сначала получает клиента, который редиректит на страницу, указанную вами в настройках Google API, то есть на /google/auth, также этот метод (redirect) принимает массив скоупов. Скоупы - это информация, которую вы хотите получить от приложения. В нашем случае мы хотим получить доступ к электронному адрес и профилю, откуда мы можем взять имя, userpic и многое другое. Дальше нас редиректит на action connectGoogleCheck(), который пробует получить пользователя по тому методу, который мы с вами ранее написали в OAuthGoogleAuthenticator (да, Symfony неявно знает, как достать именно ваш кастомный Authenticator). Если не удалось, вы можете вернуть свою ошибку или поступить так, как вам нужно. Если удалось, возвращаем на страницу с постами.

Осталось настроить файл конфигурации. Для этого откройте config/packages/security.yaml и напишите в нем следующее:

Код доступен только после покупки курса по фреймворку Symfony 4.

Мы настроили провайдер, который будет доставать пользователя по email, указанные в качестве значения к ключу property. А также указали наш собственный guard. Теперь вы можете добавить ссылку и сделать красивую кнопку, по которой запустится весь процесс авторизации:

Код доступен только после покупки курса по фреймворку Symfony 4.

P.S.

Не забудьте обновить вашу таблицу следующими командами:

Код доступен только после покупки курса по фреймворку Symfony 4.

Теперь у вас рабочая авторизация через Google. В следующей статье мы сделаем то же самое с Github.

Курс программирования на PHP
Подготовка до уровня устройства на работу!
Начать бесплатно
Комментарии (0)
Самый понятный курс PHP
Онлайн-уроки в удобное время!
Начать бесплатно
Популярное за сутки
Онлайн-курсы PHP и MySQL
Обучение с полного нуля до уровня джуниора!
Начать бесплатно
Сейчас читают
Онлайн-курсы PHP и MySQL
Обучение с полного нуля до уровня джуниора!
Начать бесплатно
Новые статьи
Логические задачи с собеседований