Розробка авторизації через email з підтвердженням
Email-верифікація — друга по розповсюдженості проблема після «Forgot Password»: лист не прийшов, потрапив у спам, посилання істекло, користувач натиснув на посилання на іншому пристрої та не розуміє чому ніщо не відбувається. Більшість цих проблем вирішується на етапі проектування, а не після скарг користувачів.
Два типи верифікації та їх відмінності
Magic Link — лист з посиланням, клік на яке мгновенно авторизує користувача. Ніякого пароля. Зручно, але вимагає, щоб користувач мав доступ до email саме у момент входу. Підходить для B2B-інструментів, де користувачі часто за комп'ютером.
Email + OTP-код — лист з 6-значним кодом, який користувач вводить у додатку. Користувач відкриває додаток → запрошує код → переключається в пошту → запам'ятовує/копіює код → повертається в додаток → вводить. Більше кроків, але працює без deep link інфраструктури.
Для мобільних додатків Magic Link технічно складніше, але дає кращий UX: натискання на посилання в листі → система відкриває додаток через Universal Links (iOS) / App Links (Android) → користувач авторизований.
Реалізація Magic Link через Universal Links
iOS Universal Links вимагають файл apple-app-site-association (AASA) на домені. Розміщується за https://yourdomain.com/.well-known/apple-app-site-association без розширення, content-type application/json. iOS завантажує цей файл при установці й кешує.
{
"applinks": {
"apps": [],
"details": [{
"appID": "TEAMID.com.yourcompany.app",
"paths": ["/auth/verify/*"]
}]
}
}
Посилання у листі: https://yourdomain.com/auth/verify/TOKEN. При кліку на iOS — система перевіряє AASA, якщо шлях співпадає — відкриває додаток через UIApplicationDelegate.application(_:continue:restorationHandler:) або onOpenURL у SwiftUI. Додаток витягує токен з URL, відправляє на backend, отримує auth tokens.
На Android — App Links з assetlinks.json за https://yourdomain.com/.well-known/assetlinks.json. Intent Filter у маніфесті:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https" android:host="yourdomain.com" android:pathPrefix="/auth/verify/"/>
</intent-filter>
Критичний edge case: користувач відкрив лист на комп'ютері, натиснув на посилання — браузер відкрив веб-сторінку, яка повинна показати «Повертайтесь у додаток та увійдіть через код». Веб-сторінка генерує той же токен у QR-код або пропонує скопіювати код вручну. Пропуск цього сценарію — частою помилка.
Інший edge case: якщо AASA-файл недоступний при установці додатку (наприклад, помилка сервера) — Universal Links не працюють, посилання відкриваються у браузері. Потрібен fallback: веб-сторінка з кнопкою «Відкрити у додатку» через Custom URL Scheme (myapp://auth/verify/TOKEN) як резервний варіант.
Email delivery: що впливає на доставляємість
Лист з кодом у папці «Спам» — смерть для конверсії. Ключові фактори:
- SPF, DKIM, DMARC — обов'язкова налаштування DNS записів. Без них Gmail та Outlook агресивно фільтрують.
- Transactional email провайдер — SendGrid, Postmark, Mailgun, Amazon SES. Не відправляти через SMTP власного сервера — IP холодний, reputation нульова.
-
From-адреса — реальний домен, не
noreply@yourdomainбез DMARC. Кращеhello@yourdomain— менше спам-триггерів. - Текст листа — не повинен містити «FREE», «Click here to win», все у верхньому регістрі. Тільки функціональний текст: «Ваш код для входу: 847293».
TTL токена: 15-30 хвилин для OTP-коду, 1 година для Magic Link. Після використання — токен негайно інвалідується (однократне використання). Зберігаємо hash токена, не сам токен.
Терміни: від 1 до 2 тижнів. Включає обидва сценарії (Magic Link + OTP fallback), налаштування email-провайдера, Universal Links / App Links, обробку edge case з браузерним відкриттям посилання.







