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» стане активною, і ви зможете відправити запит на верифікацію.

Висновок

В останньому кроці ми отримали таку інформацію про користувача як ім'я, прізвище, адресу електронної пошти і т.д. Цієї інформації повинно вистачити, щоб перевірити наявність користувача в базі даних і внести його туди в разі відсутності.