Проблема традиційних Magic Links у сучасному вебі
Посилання для швидкої авторизації (Magic Links) тривалий час вважалися стандартом безпарольного входу. Проте на практиці цей механізм регулярно створює тертя для користувачів. Найпоширеніші сценарії збоїв включають роботу у внутрішніх браузерах соцмереж (in-app browsers), корпоративні поштові фільтри, які автоматично перевіряють та «спалюють» одноразові посилання ще до кліку, а також конфлікти відкриття у мобільних застосунках замість веб-інтерфейсу.
Використання 6-значного цифрового OTP-коду (One-Time Password) повністю усуває проблему deep link. Користувач залишається на тій самій сторінці чи екрані, переглядає код у повідомленні та просто вводить його у форму. Розглянемо правильну реалізацію цієї схеми в стеку Next.js (App Router) та Supabase.
Крок 1. Налаштування поштового шаблону в Supabase
За замовчуванням Supabase надсилає посилання з підтвердженням. Щоб змінити логіку на відправку коду, перейдіть до панелі керування проектом (Authentication → Email Templates → Magic Link) та замініть стандартний блок посилання на змінну токена {{ .Token }}.
Важливо переконатися, що у шаблоні не залишилося змінної {{ .ConfirmationURL }}, інакше поштовий клієнт отримає і посилання, і код, що заплутає користувача. Для продакшн-середовища обов'язково підключіть власний SMTP-провайдер (Resend, Postmark або AWS SES), оскільки вбудований поштовий сервіс має жорсткі ліміти відправки.
Крок 2. Серверний клієнт та обробка кукі
Для коректної роботи авторизації в середовищі Next.js App Router необхідно налаштувати серверний клієнт за допомогою бібліотеки @supabase/ssr. Це забезпечує надійне читання та оновлення авторизаційних cookies безпосередньо у серверних компонентах і Route Handlers.
Крок 3. Відправка коду та захист від перебору акаунтів
Ендпоінт генерації OTP повинен враховувати два критичні фактори безпеки:
- Обмеження запитів (Rate Limiting) за IP: запобігає спаму поштовими запитами та перевитратам лімітів SMTP.
- Захист від перебору адрес (Account Enumeration): сервер повинен повертати однаковий успішний статус незалежно від того, чи зареєстрований користувач із зазначеним email у базі.
Виклик функції supabase.auth.signInWithOtp з параметром shouldCreateUser: true відправляє 6-значний токен на пошту користувача або реєструє новий профіль, якщо обліковий запис ще не існує.
Крок 4. Верифікація коду з прив'язкою ліміту до Email
Шестизначний код має лише один мільйон комбінацій. За відсутності захисту зловмисник може перебрати валідний токен автоматизованим скриптом за лічені хвилини. Тому валідацію через supabase.auth.verifyOtp потрібно обмежувати строго за email-адресою, а не за IP, оскільки боти здатні легко змінювати IP-адреси.
Оптимальне обмеження — не більше 5 спроб введення на 10 хвилин для одного акаунта. Після успішної верифікації Supabase автоматично зберігає сесійні токени в HTTP-only cookies.
Крок 5. Актуалізація сесії через Middleware
Щоб користувач не втрачав авторизацію під час переходів між сторінками, у middleware.ts реалізується перевірка та автооновлення токенів. Важливе правило безпеки: для прийняття рішень щодо доступу на сервері завжди використовуйте метод supabase.auth.getUser(), оскільки він валідує актуальність користувача безпосередньо в базі даних, на відміну від локального читання cookie-сесії.
Висновки для бізнесу
Перехід на 6-значні цифрові коди підвищує коефіцієнт завершення реєстрації та зменшує кількість звернень до технічної підтримки через «непрацюючі посилання». Команда ViAcore рекомендує закладати надійне rate-limiting та захист сесій ще на етапі проектування архітектури, забезпечуючи швидкий і безпечний користувацький досвід.
Послуги з цієї теми
Лендінг під ключ
Продаючий лендінг під ключ: оффер, структура, дизайн, розробка, SEO-техоснова та запуск реклами. Від 10 000 грн.
від 10 000 грн
Корпоративний сайт
Корпоративний сайт під ключ: презентація компанії, каталог послуг, CRM, адмін-панель, SEO-структура. Від 18 000 грн.
від 18 000 грн
Інтернет-магазин
Інтернет-магазин під ключ: каталог товарів, кошик, онлайн-оплата, інтеграції з CRM та складом, SEO-структура. Від 25 000 грн.
від 25 000 грн
Потрібно таке для вашого проєкту?
Розробка під ключ: аналіз → реалізація → запуск → підтримка. Розкажіть про задачу — відповімо з оцінкою.
Релевантні статті
Тестування REST та GraphQL контрактів у Cypress поруч із UI
Дізнайтеся, як перевірка API-контрактів поруч із UI-тестами в Cypress допомагає швидше знаходити помилки та підвищує надійність вебдодатків.
Сучасна архітектура статичних сайтів: як автоматизувати контроль якості та прискорити релізи
Як еволюція інструментів генерації статичних сторінок допомагає бізнесу прискорити релізи сайтів і гарантувати бездоганну якість коду перед публікацією.
Від прототипу до високих навантажень: як побудувати надійну LLM-архітектуру
Дізнайтеся, як побудувати відмовостійку архітектуру для AI-сервісів, уникнути збоїв під навантаженням та захистити бізнес-логіку застосунку.
Інтеграція локальних LLM у веб-додатки: альтернатива дорогим хмарним API
Дізнайтеся, як інтеграція локальних відкритих моделей штучного інтелекту допомагає бізнесу знизити витрати, гарантувати приватність даних і масштабувати веб-сервіси.
Тестування чорної скриньки: як перевірити сайт або сервіс очима користувача
Дізнайтеся, що таке тестування чорної скриньки (Black Box Testing), як воно допомагає бізнесу перевіряти цифрові продукти та чому захищає прибуток.
Безпека ШІ-інтеграцій: чому Prompt Injection не лікується як звичайна SQL-вразливість
Розбираємо, чому класичні методи захисту баз даних не працюють для мовних моделей і як побудувати безпечну архітектуру для ШІ-агентів.