Укр
OAuth 2.0 аутентификация через Google: как реализовать вход через Google на сайте

OAuth 2.0 аутентификация через Google: как реализовать вход через Google на сайте

  • 21 сентября, 2021
  • читать 10 мин
Станислав Протасевич
Станислав Протасевич Senior PHP Developer/Team Lead в Tapmedia, Преподаватель Компьютерной школы Hillel.

Всем привет!

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

Итак, начнёмс.

Для дальнейших шагов вам понадобится активный Google аккаунт

Все шаги будут характерны для локального сервера с тестовым доменом auth.lol

Шаг #1. Регистрация нового проекта

Для начала необходимо создать проект в Google Cloud Platform.

Шаг #2. Регистрация приложения

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

Шаг #2.1. Настройка экрана согласия

Отправляемся на страницу APIs & Services. OAuth consent screen для того, чтобы выбрать режим экрана согласия, на который будут перенаправлены пользователи при попытке входа через Google на вашем сайте.

Выбираем один из режимов работы данного экрана:

  • Internal: аутентификация будет возможна только для пользователей вашей организации. Т.е. это некий корпоративный вариант, без верификации.
  • External: аутентификация будет доступна для всех пользователей, включая тестовых. Для выкатки на продакшн потребуется верификация.

В нашем случае выбираем пункт External.

После нажатия на кнопку «Create» попадаем на первый шаг: настройку экрана согласия.

Вводим информацию о нашем приложении:

  • Название приложения
  • Электронную почту технической поддержки
  • Загружаем логотип (по желанию)

Далее необходимо ввести подробную информацию о нашем домене. В нашем случае будем вводить тестовые данные:

  • Ссылка на главную страницу приложения
  • Ссылка на страницу условий конфиденциальности
  • Ссылка на страницу с положениями и условиями использования

Далее следует очень важный параметр:

  • Домены авторизации

Ну и в конце добавляем контактную информацию разработчика:

Нажимаем на кнопку «Save and continue» и переходим к следующему шагу.

Шаг #2.2. Настройка запрашиваемых прав

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

Нажимаем на кнопку «Add or remove scopes».

В открывшемся блоке запрашиваем права на доступ к адресу электронной почты пользователя, а также информацию о профиле:

  • .../auth/userinfo.email
  • .../auth/userinfo.profile

Прокручиваем блок вниз и нажимаем на кнопку «Update». На основной странице жмём «Save and continue».

Шаг #2.3. Настройка тестовых пользователей

Далее следует добавить одного или несколько тестовых пользователей. Для этого жмём на кнопку «Add users».

В открывшемся блоке добавляем тестовый email и нажимаем на кнопку «Add».

Далее жмём на «Save and continue» и переходим к финальному шагу настройки приложения.

Шаг #2.4. Сводная информация

На последней странице настройки приложения вы увидите всю сводную информацию, которую вводили на предыдущих шагах. Если какой-то блок требует редактирования, то жмём кнопку «Edit». В противном случае можем приступать к следующим шагам.

Шаг #3. Генерация ключей доступа

Далее необходимо отправиться на страницу APIs & Services. Credentials и сгенерировать данные, которые будут использоваться для аутентификации созданного приложения.

После загрузки страницы нажимаем на кнопку «Create credentials» и выбираем пункт «OAuth client ID», чтобы сгенерировать новый ключ доступа.

На открывшейся странице заполняем очередную форму:

  • Тип приложения: Web application
  • Название

В секции «Authorized redirect URIs» вводим адрес, на который пользователь будет направляться после экрана согласия. То есть, это должна быть какая-то страница на нашем сайте, которая будет отвечать за обработку данных пользователя.

Далее жмём на кнопку «Create» и получаем ключи доступа.

Сохраняем данную информацию, ведь она будет необходима в наших последующих скриптах.

Шаг #4. Создание файла настроек

Теперь было бы неплохо организовать один файл, в который мы поместим все необходимые параметры для реализации последующей аутентификации.

Создадим файл settings.php и добавим все необходимые URI, которые нам понадобятся для полного прохождения процедуры аутентификации и запросе данных о пользователе:

// Права доступа
const GOOGLE_SCOPES = [
    'https://www.googleapis.com/auth/userinfo.email', // доступ до адреси електронної пошти
    'https://www.googleapis.com/auth/userinfo.profile' // доступ до інформації профілю
];

// Посилання на аутентифікацію
const GOOGLE_AUTH_URI = 'https://accounts.google.com/o/oauth2/auth';

// Посилання на отримання токена
const GOOGLE_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';

// Посилання на отримання інформації про користувача
const GOOGLE_USER_INFO_URI = 'https://www.googleapis.com/oauth2/v1/userinfo';

Далее создадим ещё несколько констант, куда поместим информацию, которая была сгенерирована во время регистрации приложения:

// Client ID з кроку #3
const GOOGLE_CLIENT_ID = '684769382355-4beq4rgnhqspdblilusm265ppm4h6gev.apps.googleusercontent.com';

// Client Secret з кроку #3
const GOOGLE_CLIENT_SECRET = 'twd431H4VS59bJuxM4qyDcZJ';

// Посилання з секції "Authorized redirect URIs" з кроку #3
const GOOGLE_REDIRECT_URI = 'http://auth.lol/callback.php';

Шаг #5. Генерация ссылки

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

Для начала подключаем файл настроек из шага #4:

require_once 'settings.php';

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

$parameters = [
    'redirect_uri'  => GOOGLE_REDIRECT_URI,
    'response_type' => 'code',
    'client_id'     => GOOGLE_CLIENT_ID,
    'scope'         => implode(' ', GOOGLE_SCOPES),
];

Собираем URI, используя константу с фрагментом адреса и массив параметров:

$uri = GOOGLE_AUTH_URI . '?' . http_build_query($parameters);

Теперь в нужном месте страницы выведем данную ссылку:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <a href="<?= $uri ?>">OAuth 2.0 аутентифікація через Google</a>
</body>
</html>

На самой странице это будет выглядеть примерно так:

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

Далее пользователь будет перенаправлен обратно на ваш сайт по адресу, указанному в секции «Authorized redirect URIs» шага #3.

Шаг #6. Получение токена доступа

На последнем шаге мы были перенаправлены обратно на наш сайт GET запросом со специальными параметрами. В них зашит код (code), который поможет достать токен доступа (Access Token). С помощью него мы сможем общаться с Google API и доставать нужную информацию о пользователе.

Чтобы получить токен доступа, необходимо отправить POST запрос с полученным кодом и дополнительными параметрами. Для того, чтобы отправлять HTTP запросы из скрипта было проще, подключим библиотеку Guzzle.

composer require guzzlehttp/guzzle

Далее подключим авто-загрузчик и файл настроек в файле callback.php:

require_once 'vendor/autoload.php';
require_once 'settings.php';

Формируем массив параметров для подключения токена доступа. На этот раз нам понадобится секретный ключ (GOOGLE_CLIENT_SECRET) и GET-параметр code:

$parameters = [
    'client_id'     => GOOGLE_CLIENT_ID,
    'client_secret' => GOOGLE_CLIENT_SECRET,
    'redirect_uri'  => GOOGLE_REDIRECT_URI,
    'grant_type'    => 'authorization_code',
    'code'          => $_GET['code'],
];

Инициализируем HTTP клиент и делаем запрос на получение токена:

$client = new \GuzzleHttp\Client();

$response = $client->post(GOOGLE_TOKEN_URI, ['form_params' => $parameters]);

Обратите внимание, что данный POST запрос должен отправляться как будто через форму. Именно поэтому мы передали параметры в специальном ключе form_params. Если вы будете делать аналогичное действие не через Guzzle, то убедитесь, что форма будет отправлена с заголовком application/x-www-form-urlencoded

Ответ от Google мы получим в формате JSON, поэтому конвертируем его в ассоциативный массив:

$data = json_decode($response->getBody()->getContents(), true);

В результате получим следующие данные, среди которых есть и токен доступа (access_token):

Шаг #7. Получение данных о пользователе

Первым делом можем сохранить токен доступа в отдельную переменную:

$token = $data['access_token'];

Чтобы получить информацию о пользователе, необходимо отправить GET запрос со специальным заголовком Authorization, указав в качестве значения Bearer <token>. Пробел обязателен!

$response = $client->get(GOOGLE_USER_INFO_URI, [
    'headers' => [
        'Authorization' => 'Bearer ' . $token
    ]
]);

В качестве ответа получим JSON с информацией о пользователе. Конвертируем его в ассоциативный массив для дальнейших действий.

$data = json_decode($response->getBody()->getContents(), true);

Пример ответа:

Верификация приложения

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

Для прохождения верификации необходимо вместо тестовых доменов указать реальные, с использования протокола https. В этом случае на странице редактирования экрана согласия, в секции «Publishing status» вы сможете переключиться с режима Testing на In Production.

После замены тестовых доменов на реальные с использованием HTTPS, кнопка «Publish App» станет активной, и вы сможете отправить запрос на верификацию.

Заключение

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