Авторизация в приложении: SMS-код, вход через Apple и Google
Практика4 минРедакция Innovialabs
Коротко
Для приложения в СНГ разумный базовый набор — вход по номеру телефона с SMS-кодом плюс Google и Apple; токены хранятся в Keychain/Keystore, а сессия продлевается через refresh token.
Короткий ответ
Универсального метода нет, но рабочий набор по умолчанию для большинства приложений в Узбекистане и СНГ такой:
- Номер телефона + одноразовый код — основной вход, потому что телефон есть у всех и он часто нужен бизнесу (доставка, звонок курьера).
- Sign in with Google и Sign in with Apple — быстрый вход в один тап для тех, кто не хочет вводить код.
- Короткий access token и долгий refresh token, хранящиеся в защищенном хранилище системы.
Дальше — детали, на которых чаще всего ошибаются.
Сравнение способов входа
| Способ | Плюсы | Минусы |
|---|---|---|
| SMS-код | Привычно, телефон сразу подтвержден | Платные SMS, задержки доставки, фрод |
| Один тап на Android, без паролей | Не у всех пользователей iOS есть аккаунт Google | |
| Apple | Один тап на iOS, можно скрыть email | Нет номера телефона, email может быть прокси |
| Email + пароль | Без внешних зависимостей | Забытые пароли, больше трения |
| Magic link по email | Без паролей | Неудобно переключаться между почтой и приложением |
Правило Apple о Sign in with Apple
Если в iOS-приложении есть вход через сторонние сервисы (Google, Facebook и т. п.), App Store Review Guidelines требуют предложить и равноценный вариант, ориентированный на приватность: он собирает только имя и email, позволяет скрыть email и не используется для рекламного трекинга. Sign in with Apple этим требованиям соответствует, поэтому на практике его просто добавляют рядом с Google.
Правило не касается приложений, где вход только через собственные аккаунты компании (например, телефон + SMS), а также некоторых корпоративных и образовательных сценариев. Точные формулировки меняются — сверяйтесь с актуальной версией раздела 4.8 руководства Apple.
Еще два требования, о которых забывают:
- В приложении должна быть возможность удалить аккаунт.
- При входе через Apple имя пользователя приходит только при первой авторизации — сохраните его на сервере сразу.
SMS-код: стоимость и фрод
Каждая SMS стоит денег, а цена зависит от страны, оператора и агрегатора. Главная угроза — SMS pumping: боты массово запрашивают коды на номера, с которых злоумышленники получают долю от трафика. Счет приходит вам.
Как защититься:
- Лимиты на номер, устройство и IP: не больше нескольких запросов за интервал, растущая пауза между повторами.
- Белый список стран. Если работаете только в Узбекистане, не отправляйте SMS на другие коды.
- Проверка целостности устройства — Play Integrity на Android и App Attest на iOS — чтобы запросы шли из настоящего приложения.
- Мониторинг: алерт при резком росте отправок или низкой доле подтвержденных кодов.
- Альтернативные каналы: доставка кода через мессенджер или flash call бывает дешевле, но оставьте SMS как запасной путь.
Сам код: 4-6 цифр, срок жизни несколько минут, ограниченное число попыток ввода, хранение на сервере только в виде хеша. Включите автоподстановку кода из SMS (SMS Retriever на Android, oneTimeCode на iOS).
Хранение токенов и обновление сессии
- Access token — короткоживущий, отправляется с каждым запросом.
- Refresh token — долгоживущий, используется только для получения новой пары. При каждом обновлении выдавайте новый refresh token и отзывайте старый (rotation).
- Храните токены в Keychain на iOS и в хранилище, зашифрованном ключом из Android Keystore. В Flutter для этого есть
flutter_secure_storage, в React Native —react-native-keychainилиexpo-secure-store. Не используйтеSharedPreferences,UserDefaultsилиAsyncStorageв открытом виде. - Обновляйте токен одним запросом: если несколько вызовов одновременно получили 401, остальные ждут результата первого обновления.
- На сервере храните список сессий по устройствам, чтобы пользователь мог выйти со всех устройств, а вы — отозвать украденный токен.
Частые ошибки
- Отправка SMS без лимитов и проверки страны.
- Хранение токенов в незащищенном хранилище.
- Отсутствие связывания аккаунтов: один человек вошел через Google, потом через телефон и получил два профиля.
- Требование входа до того, как пользователь увидел пользу приложения.