Разработка авторизации через 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 cases с браузерным открытием ссылки.







