Реалізація OAuth2 автентифікації: PKCE, ротація токенів, соціальний вхід

Збої входу та витоки токенів підривають довіру користувачів і репутацію. Ми проєктуємо та впроваджуємо OAuth2 під ключ: PKCE, ротація токенів, вхід через соцмережі — з гарантією стабільної роботи. Обговоримо задачу та повернемося з оцінкою і планом.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Реалізація OAuth2 автентифікації: PKCE, ротація токенів, соціальний вхід
Складний
~3-5 днів
Часті запитання

OAuth2: де ламається вхід і чому це дорожче, ніж здається

OAuth2 майже ніколи не ламається «на вході» — він ламається на деталях, які не видно в happy path.

Класика: публічний клієнт без PKCE, і код авторизації йде у відкритому вигляді через перехоплення редиректу — на мобільному пристрої або в браузері його знімає будь-який застосунок, що зареєстрував ту саму URI-схему.

Далі зловмисник обмінює код на токен раніше за легітимний клієнт, і в журналах це виглядає як звичайний успішний вхід.

Друга міна — вічні токени.

Access-токен без короткого терміну життя і refresh без ротації живе до ручного відкликання: витік із логів, із пам'яті пристрою або через сторонній скрипт дає постійний доступ, а інвалідувати його нічим — немає ні списку відкликання, ні прив'язки до пристрою. Відкликання доводиться робити зміною секретів, що валить усіх користувачів одразу.

Третій сценарій — розсинхрон сесій між сервісами. Користувач увійшов в одному застосунку, а сусідній сервіс його не бачить: різні видавці токенів, незбіжні аудиторії, роз'їхалися ключі підпису. Зовні це «відмова входу» без виразної помилки, і підтримка розбирає його наосліп.

Окремо — сплески відмов при оновленні токена. Коли refresh-запити йдуть паралельно з кількох вкладок або реплік, ротація спрацьовує на першому запиті, а решта отримують відмову і розлогінюють користувача. Пік таких збоїв припадає на ранок і на моменти деплою, коли сесії масово перезапитують доступ.

Ціна в усіх чотирьох сценаріїв одна: втрачені замовлення, навантаження на підтримку і репутаційні втрати, яких не видно в метриках доступності. Розбираємо, як це закривається.

Схема входу: PKCE, ротація токенів, вхід через соцмережі

PKCE замість implicit flow

Класичний implicit flow віддає токен прямо в адресний рядок — він осідає в історії браузера, логах проксі та заголовку Referer.

PKCE закриває цей клас: клієнт генерує випадковий code_verifier, надсилає його хеш (code_challenge) на авторизацію, а провайдер звіряє пару під час обміну коду на токен. Перехоплений код без verifier марний — атака на редирект перестає працювати в принципі.

Ротація токенів і строк життя сесії

Refresh-токен одноразовий: під час обміну видається нова пара, стара інвалідується. Якщо той самий refresh надходить повторно — це ознака крадіжки, і весь ланцюжок сесій користувача відкликається автоматично.

Access-токен живе хвилини, тому компрометація дає вікно в одиниці хвилин, а не дні. Строк життя сесії задається політикою: для адміністративних розділів — години, для звичайних — дні з продовженням за активністю.

Вхід через соцмережі та відкликання доступу

Зовнішній провайдер повертає підписаний ідентифікатор, за яким ми знаходимо або створюємо локальний обліковий запис — прив'язка йде за стабільним ідентифікатором, а не за поштою, тому зміна адреси не породжує дубль.

Відкликання доступу миттєве: запис у списку токенів, що відкликаються, перевіряється на кожному запиті, і сесія вмирає в межах кешу перевірки.

Варіант Коли підходить Обмеження
PKCE + ротація Публічні клієнти, мобільні та SPA Потрібен серверний обмін коду
Класичний серверний потік Конфіденційні клієнти з секретом Секрет витікає разом із бекендом
Довгоживучий токен Внутрішні сервіси без користувача Відкликання запізнюється, вікно атаки зростає

Схему збираємо на Keycloak або на вбудованому провайдері — вибір залежить від того, чи потрібен єдиний вхід у сторонні системи.

Порядок робіт: від аудиту поточного входу до передачі налаштувань

Роботи виконуються послідовно: кожен наступний етап спирається на артефакти попереднього, тому проміжні рішення не доводиться переглядати на середині. Нижче — як влаштований процес від аудиту входу до передачі налаштувань.

  1. Аудит поточного входу. Розбираємо, як застосунок видає та зберігає токени, де живуть сесії, які провайдери вже підключені та які потоки OAuth2 використовуються.

    Фіксуємо слабкі місця: довгоживучі refresh-токени без ротації, відсутність PKCE для публічних клієнтів, токени в localStorage, відсутність відкликання при виході.

  2. Проєктування потоків. Обираємо Authorization Code + PKCE для клієнтів, які не можуть зберігати секрет, і визначаємо терміни життя access- та refresh-токенів.

    Проєктуємо ротацію refresh-токенів із виявленням повторного використання: при спробі застосувати вже відкликаний токен весь ланцюжок інвалідується.

  3. Налаштування провайдерів і політик. Реєструємо застосунок у провайдерів, налаштовуємо redirect-адреси, scopes та правила зіставлення облікових записів при social login. Прописуємо політики відкликання, зберігання та прив'язки кількох способів входу до одного користувача.

  4. Перевірка сценаріїв відмови. Прогоняємо те, що зазвичай ламається в проді: прострочений refresh-токен, відкликання доступу на боці провайдера, розсинхрон годинників, повторний колбек, конфлікт облікових записів при вході через різні сервіси. Кожен сценарій має завершуватися передбачуваним станом, а не завислою сесією.

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

Опишіть вашу поточну схему входу — повернемося з оцінкою та планом робіт.

Чим відрізняється код авторизації з PKCE від неявного потоку?

Неявний потік (implicit flow) був компромісом епохи, коли браузери не вміли надійно зберігати секрети, а сервери авторизації не підтримували обмін коду на токен без участі бекенду.

У ньому клієнтський застосунок отримує access token прямо у фрагменті адресного рядка — минаючи проміжний крок із кодом.

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

Саме тому OAuth2 в актуальній редакції прямо не рекомендує неявний потік для клієнтських застосунків.

Код авторизації з PKCE вирішує те саме завдання інакше. Застосунок генерує випадкове значення (code_verifier), обчислює з нього похідну (code_challenge) і надсилає її разом із запитом на вхід.

Сервер повертає одноразовий код, а обмін коду на токен можливий лише за пред'явлення вихідного verifier. Навіть якщо зловмисник перехопить код — через редирект, логи або шкідливий застосунок на пристрої, — без verifier він марний.

Це закриває клас атак із перехопленням коду авторизації, який у неявному потоці просто був відсутній як етап.

Ключова відмінність — де опиняється токен. У неявному потоці він одразу потрапляє в клієнтське середовище й живе там до закінчення терміну. У потоці з PKCE токен видається лише після перевірки verifier, а сам код одноразовий і прив'язаний до конкретного запиту.

Для мобільних і односторінкових застосунків, де немає довіреного бекенду, це єдиний коректний варіант: секрет клієнта там зберігати ніде, а PKCE замінює його криптографічною прив'язкою.

Є й друга лінія захисту — refresh rotation. Довгоживучий refresh token при кожному оновленні замінюється новим, а старий інвалідується. Якщо токен украли й використали, легітимний клієнт при наступному оновленні отримає відмову, і весь ланцюжок сесій відкликається.

У неявному потоці refresh token взагалі не видавався — продовжити сесію можна було лише повторним входом, що штовхало розробників до подовження терміну життя access token і зростання вікна уразливості.

На практиці вибір виглядає так: для серверних застосунків із довіреним бекендом — код авторизації із секретом клієнта; для односторінкових і мобільних — код авторизації з PKCE; неявний потік залишається лише в успадкованих системах, де його заміна потребує перезбирання клієнта.

Безпека входу тут вимірюється не зручністю інтеграції, а тим, скільки класів атак закрито на рівні протоколу, а не на рівні дисципліни розробника.

Кейс: вхід перестав відвалюватися після ротації токенів

Клієнт — сервіс з особистим кабінетом і мобільним застосунком — звертався зі скаргою, яку підтримка не могла закрити: користувачі регулярно скаржилися, що «вхід злітає».

Частка невдалих входів трималася на рівні 8%: частина запитів на оновлення токена надходила з уже використаним значенням, сервер відповідав відмовою, і людина бачила форму логіна замість кабінету.

Окремий біль — відкликання доступу: після блокування співробітника його сесія жила до закінчення терміну дії токена, тобто доступ зберігався годинами.

Що змінили

Розібрали потік автентифікації покроково і знайшли корінь: застосунок оновлював токен паралельно з кількох вкладок і фонових задач, а старий токен при цьому не інвалідовувався атомарно.

Запровадили ротацію токенів оновлення: кожен обмін видає нову пару, попереднє значення позначається використаним, а повторне пред'явлення трактується як ознака витоку — весь ланцюжок сесій користувача відкликається.

Гонку між вкладками закрили на стороні клієнта: обмін іде через єдину точку з блокуванням, інші запити чекають результату, а не ініціюють свій.

Для входу через зовнішніх провайдерів підключили PKCE — код авторизації більше не проходить у відкритому вигляді, перехоплений редірект без верифікатора марний.

Відкликання доступу перевели на серверний реєстр активних сесій: адміністратор закриває доступ, і всі пов'язані токени стають недійсними в момент відкликання, а не після закінчення терміну.

Що стало

Метрика До Після
Частка невдалих входів ~8% менше 0,5%
Час відкликання доступу до терміну життя токена секунди після відкликання
Звернення до підтримки щодо скидання сесій регулярний потік поодинокі випадки

Окремо закрили сценарій зміни пароля: він тепер завершує всі інші сесії, крім поточної, — раніше користувач змінював пароль і не розумів, чому стара сесія на іншому пристрої продовжує працювати.

Логіку будували на стандартному протоколі авторизації OAuth 2.0 з розширеннями PKCE і ротацією токенів оновлення — без саморобних схем, які потім важко підтримувати і перевіряти на безпеку.

Сумніви перед впровадженням: сумісність, міграція, відкат

Впровадження OAuth2 майже ніколи не починається з нуля: у замовника вже є база користувачів, власні сесії, ролі та зовнішні сервіси, які звертаються до застосунку за старими правилами.

Тому перше питання — не «як налаштувати провайдера», а «що буде з поточними входами, поки ми переводимо систему на новий контур».

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

Окремо фіксуємо план відкату — якщо на проді виявиться несумісність, повернення до попередньої схеми займає хвилини, а не години.

Що якщо у нас нестандартний провайдер або власна база користувачів? OAuth2 розширюємо через власний провайдер ідентифікації: він віддає ті самі дані, що й зовнішні, і підключається до наявної бази без її перебудови. Що якщо частина сервісів не вміє працювати з токенами?

Для них залишаємо сумісний шар доступу, який приймає попередній формат і всередині перевіряє новий — сервіс не переписується повністю.

Чи можна відкотитися, якщо новий вхід зламає частину сценаріїв?

Так. Ми тримаємо обидва контури активними і перемикаємо трафік за часткою користувачів: у разі проблеми повертаємо попередній вхід одним налаштуванням, не відкочуючи реліз повністю. Усі видані токени при цьому залишаються валідними, сесії не розриваються.

На руки замовник отримує не «працює і гаразд», а комплект, за яким систему можна супроводжувати й передати іншій команді:

  • конфігурації провайдерів — які параметри задані й чому;
  • схеми потоків входу: де видається токен, де перевіряється, де оновлюється;
  • політики строків життя токенів і правила їх відкликання;
  • матрицю доступів: хто і до яких даних отримує доступ після входу;
  • документацію щодо підключення нових сервісів і зовнішніх провайдерів;
  • план відкату з точками перемикання та критеріями спрацювання;
  • інструкцію для підтримки: як читати логи входу та знаходити причину відмови.

Опишіть вашу поточну схему входу та список сервісів, які до неї підключені, — повернемося з оцінкою та планом переведення без зупинки роботи.

Терміни етапів впровадження OAuth2 без прив'язки до дат

Впровадження OAuth2 розбивається на етапи з різною тривалістю — від швидких перевірок до робіт, де основний час іде на узгодження сценаріїв і тестування.

Нижче — орієнтовні терміни для типового проєкту: вони залежать від кількості зовнішніх провайдерів, кількості ролей і того, чи вже є готова інфраструктура автентифікації.

Найдовше триває інтеграція — саме там випливають розбіжності між моделлю користувачів у провайдера та вашою внутрішньою структурою ролей.

Перевірка займає окремий блок: сценарії із закінченням токена й одночасним оновленням з кількох вкладок ламаються найчастіше, і їх краще закрити до передачі.

Чи можна прискорити? Так, якщо зовнішній провайдер один і ролі вже описані — етап проєктування скорочується вдвічі. Якщо провайдерів кілька і потрібен єдиний обліковий запис, терміни зростають пропорційно до кількості інтеграцій.

Що якщо частину робіт уже зроблено? Аудит покаже, що перевикористаємо, а що доведеться переписати — від цього залежить, стартуємо ми з проєктування чи із середини налаштування.

Опишіть вашу задачу: скільки точок входу, які провайдери, чи є поточна схема сесій — повернемося з оцінкою та планом за етапами.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060