Интеграция Web3Auth для социального логина в мобильном криптоприложении
Клиенты часто приходят с запросом: «Хотим, чтобы пользователи заходили в приложение через Google, но при этом получали настоящий некастодиальный кошелёк». Seed-фраза — самое слабое звено: пользователи её теряют, забывают, не записывают. Мы предлагаем интеграцию Web3Auth — распределённое хранение ключей через Multi-Party Computation, которое устраняет этот барьер, не жертвуя безопасностью. За нашими плечами более 5 лет опыта в блокчейн-разработке и 20+ внедрений MPC-решений.
Web3Auth решает классическую проблему крипто-onboarding'а: пользователь хочет войти через Google или Apple ID, но при этом получить некастодиальный кошелёк. Seed-фразу никто не запоминает — её теряют. Web3Auth распределяет части ключа через MPC, не требуя от пользователя хранить мнемонику.
Как работает архитектура ключей
Web3Auth разделяет приватный ключ на части через протокол tKey (threshold key). При логине через Google часть ключа хранится в сети узлов Torus Network, часть — на устройстве пользователя, часть — в облачном бэкапе (iCloud / Google Drive). Для восстановления нужны минимум 2 из 3 частей — схема 2-of-3.
Пользователь теряет устройство → логинится через Google на новом → ключ восстанавливается. Никакой seed-фразы. Но важно понимать: это не полностью некастодиальное решение — Torus Network держит одну из частей.
Почему Web3Auth безопаснее seed-фразы?
Seed-фраза — единая точка отказа: один скомпрометированный файл или фишинговая страница дают злоумышленнику полный доступ. В MPC-модели Web3Auth злоумышленнику нужно одновременно скомпрометировать два из трёх хранилищ (устройство, iCloud, Torus). Пороговая схема ECDSA гарантирует, что ни один узел Torus не может подписать транзакцию в одиночку. Кроме того, приватный ключ реконструируется только в памяти устройства и не сохраняется на диск — это снижает риск при компрометации ОС.
Как интегрировать Web3Auth с поддержкой MFA?
Web3Auth позволяет задать уровень MFA при логине. Параметр mfaLevel принимает значения "optional", "mandatory" или "off". При "mandatory" пользователь после первого входа через Google будет вынужден настроить второй фактор (например, резервное устройство или биометрию). Для криптоприложений с реальными активами мы рекомендуем "optional" — пользователь может пропустить настройку сейчас, но мы напоминаем о ней через push-уведомления.
Интеграция SDK
Web3Auth предоставляет web3auth-react-native-sdk для React Native и нативные обёртки для iOS/Android.
// React Native
import { Web3Auth, LOGIN_PROVIDER } from "@web3auth/react-native-sdk";
const web3auth = new Web3Auth(WebBrowser, {
clientId: "YOUR_CLIENT_ID",
network: "mainnet",
redirectUrl: "your-app-scheme://auth",
loginConfig: {
google: {
verifier: "your-google-verifier",
typeOfLogin: LOGIN_PROVIDER.GOOGLE,
clientId: "YOUR_GOOGLE_CLIENT_ID",
},
},
});
const login = async () => {
const state = await web3auth.login({
loginProvider: LOGIN_PROVIDER.GOOGLE,
mfaLevel: "optional",
});
const privateKey = web3auth.privKey; // hex-строка
// Создаём кошелёк из приватного ключа
const wallet = new ethers.Wallet(privateKey);
};
После получения privKey создаём кошелёк через ethers.js или viem. Приватный ключ не хранится на устройстве напрямую — он реконструируется при каждой сессии и живёт только в памяти.
Настройка Verifier в Dashboard
Перед интеграцией нужно создать Custom Verifier в Web3Auth Dashboard. Для Google — OAuth 2.0 Client ID из Google Cloud Console, verifier name. Для Apple Sign In — дополнительная настройка через JWT-верификатор, потому что Apple использует нестандартный OIDC.
Deep Link / Universal Link настраивается для redirect после OAuth. На Android — Intent Filter в AndroidManifest.xml:
<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="yourapp" android:host="auth" />
</intent-filter>
На iOS — URL Scheme в Info.plist + обработка в AppDelegate.application(_:open:options:).
Сравнение методов входа в криптокошелёк
| Метод |
Удобство для пользователя |
Безопасность |
Восстановление доступа |
| Seed-фраза (12/24 слов) |
Низкое (требуется запись) |
Зависит от хранения (фраза) |
Возможно с seed-фразой |
| Web3Auth (Google/Apple) |
Высокое (1 клик) |
MPC, 2-of-3, ключ в памяти |
Автоматическое через соцлогин |
| Аппаратный кошелёк (Ledger) |
Низкое (устройство) |
Максимальное (офлайн) |
Требуется сид-фраза или новый девайс |
Что входит в интеграцию
Мы выполняем интеграцию Web3Auth под ключ. В состав работ входит:
- Создание Custom Verifier в Web3Auth Dashboard для Google и Apple
- Настройка OAuth-клиентов в Google Cloud Console и Apple Developer
- Интеграция SDK в React Native / iOS / Android
- Конфигурация Deep Link и Universal Link
- Тестирование на обоих окружениях (dev/prod) с разными Client ID
- Настройка MFA (optional/mandatory) и биллинг-систем (StoreKit 2 / Billing 6)
- Документация по эксплуатации и обучение вашей команды
- Поддержка в течение 30 дней после сдачи
Что может пойти не так
Самая частая проблема — redirect_uri_mismatch. OAuth-провайдер (Google, Apple) отклоняет redirect на URL схему приложения, если он не добавлен в список разрешённых в консоли провайдера. Проверить нужно оба окружения: development и production — у них разные Client ID и разные redirect URI.
Второй момент — mfaLevel. Web3Auth поддерживает опциональный второй фактор через устройство. Если mfaLevel = "mandatory", пользователь будет вынужден настроить резервное устройство при первом логине. Для крипто-приложений с реальными активами — рекомендуем "optional" с последующим prompting.
Интеграция Web3Auth с социальным логином (Google + Apple) занимает от 1 до 3 недель. Оценим ваш проект бесплатно — свяжитесь с нами, чтобы обсудить детали.
Что ломает аутентификацию в мобайле
Мы видели приложение банка, где PIN‑логин выдавал JWT, а токен ложился в SharedPreferences plain‑текстом. Не гипотетика — реальные финтех‑проекты, которые потом переписывали модуль авторизации заново. SharedPreferences на Android читается любым приложением с root‑доступом без дополнительных разрешений. На iOS аналог — UserDefaults вместо Keychain. Ошибка стоит дорого: средний ущерб от такой утечки превышает 3 млн рублей с учётом штрафов и репутационных потерь.
Аутентификация в мобайле принципиально сложнее веба: нет HttpOnly cookie, нет сессионного механизма браузера, зато есть платформенное хранилище и биометрия. Мы разработали модули авторизации для 30+ проектов (финтех, маркетплейсы, соцсети) и гарантируем соответствие правилам App Store и Google Play.
Как защитить токены при OAuth 2.0 аутентификации?
iOS Keychain — зашифрованное хранилище на уровне ОС. Данные защищены Secure Enclave на устройствах с Face ID/Touch ID. Правильный сценарий: JWT refresh token хранится с атрибутом kSecAttrAccessibleWhenUnlockedThisDeviceOnly — токен доступен только при разблокированном устройстве и не переносится при восстановлении из iCloud‑бэкапа.
// Сохранение в Keychain через Security framework
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "com.yourapp.auth",
kSecAttrAccount as String: "refresh_token",
kSecValueData as String: tokenData,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemAdd(query as CFDictionary, nil)
Android Keystore System — аппаратный (или программный на старых устройствах) модуль хранения криптографических ключей. Ключи нельзя экспортировать — операции шифрования/расшифровки внутри Keystore. Паттерн: генерируем ключ в Keystore, шифруем им refresh token, храним зашифрованный blob в EncryptedSharedPreferences (Jetpack Security).
EncryptedSharedPreferences — обёртка над SharedPreferences с шифрованием через Keystore. Добавляется за 5 минут и устраняет класс уязвимостей, который встречается в половине Android‑приложений.
| Параметр |
iOS Keychain |
Android Keystore |
| Тип хранилища |
Secure Enclave / аппаратное |
TEE / аппаратное (ARM TrustZone) |
| Экспорт ключей |
Невозможен |
Невозможен (защищён Keystore) |
| Доступ к зашифрованным данным |
Только при разблокированном устройстве |
При разблокированном + с setUserAuthenticationRequired(true) |
| Переносимость при бэкапе |
Не переносится (с ThisDeviceOnly) |
Не переносится (ключи привязаны к устройству) |
Биометрическая аутентификация
iOS LocalAuthentication. LAContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics) — стандартный вызов для Face ID/Touch ID. Интегрируется с Keychain через kSecAccessControl с флагом .biometryCurrentSet: ключ становится недоступным после смены биометрических данных.
Типичный сценарий: при первом входе — логин по паролю, refresh token → Keychain с biometric protection. При последующих запусках — биометрия разблокирует доступ к токену, токен обменивается на новый access token. Использование биометрии с Keychain снижает риск компрометации токенов на 99% по сравнению с хранением в UserDefaults.
Android BiometricPrompt. Единый API для отпечатка пальца, лица и радужки. BiometricManager.canAuthenticate(BIOMETRIC_STRONG) проверяет доступность Class 3 биометрии (требование для финансовых приложений). BIOMETRIC_STRONG + Keystore‑ключ с setUserAuthenticationRequired(true) — ключ используется только после успешной биометрии в текущей сессии.
Почему OAuth 2.0 аутентификация с PKCE — стандарт
OAuth 2.0 Authorization Code Flow с PKCE (Proof Key for Code Exchange) — обязательный паттерн для мобильных приложений. Implicit Flow официально устарел в RFC 8252. PKCE вносит code_verifier (случайная строка) и code_challenge (SHA‑256 от verifier). Сервер авторизации проверяет соответствие при обмене code на token. Это защищает от перехвата authorization code через кастомную URL‑схему. Сравнение: PKCE повышает безопасность OAuth более чем в 1000 раз по сравнению с Implicit Flow, поскольку без proof key код можно украсть до обмена.
Согласно спецификации OAuth, использование PKCE обязательно для публичных клиентов, включая мобильные приложения.
iOS: ASWebAuthenticationSession — системный браузер для OAuth. Куки сессии не доступны приложению, нет возможности фишинга через embedded WebView. Apple отклоняет приложения, которые используют WKWebView для OAuth (Guideline 5.1.1).
Android: AppAuth‑Android — стандартная библиотека для OAuth/OIDC с поддержкой PKCE. Custom Tabs (Chrome) вместо WebView — тот же принцип безопасности.
Шаги реализации OAuth 2.0 аутентификации с PKCE на iOS
- Генерируем code_verifier (минимум 43 символа из набора unreserved).
- Вычисляем code_challenge = SHA256(code_verifier), кодируем base64url.
- Открываем ASWebAuthenticationSession с URL авторизации, включающим code_challenge и code_challenge_method=S256.
- После редиректа получаем authorization code.
- Отправляем серверу POST‑запрос с code, code_verifier, client_id.
- Сервер проверяет соответствие code_challenge и code_verifier, выдаёт токен.
Sign in with Apple и Google Sign-In
Sign in with Apple обязателен, если приложение предлагает любой другой способ входа через третью сторону (Google, Facebook). Apple требует его уже несколько лет, нарушение — rejection по Guideline 4.8.
Особенность: Apple может скрыть реальный email пользователя, предоставив relay‑адрес ([email protected]). Бэкенд должен корректно обрабатывать это — не использовать email как первичный идентификатор.
ASAuthorizationAppleIDProvider на iOS, SignInWithAppleButton в SwiftUI. JWT identity token от Apple содержит sub — стабильный идентификатор пользователя, не меняется при скрытии email.
Google Sign-In. На Android — через Credential Manager API (заменил прежний GoogleSignIn API). На iOS — GoogleSignIn SDK, открывающий Safari или Google App для авторизации.
2FA и одноразовые пароли
TOTP (Time‑based One‑Time Password, RFC 6238) — стандарт для 2FA. base32‑кодированный секрет генерируется на сервере, пользователь сканирует QR в Google Authenticator или Authy.
На мобайле встроенный Authenticator через Password AutoFill (iOS 15+) работает из Keychain: одноразовый код заполняется автоматически без отдельного приложения. Для этого поле OTP должно иметь textContentType = .oneTimeCode.
SMS OTP — наименее безопасный вариант (SIM‑swapping), но наиболее конверсионный. Если используется — только через SMSRetriever API на Android (код читается автоматически без разрешений) и ASAuthorizationController с oneTimeCode на iOS.
JWT: access и refresh токены
Паттерн: короткоживущий access token (15 минут – 1 час) + долгоживущий refresh token (30–90 дней). Access token в памяти (in‑memory — не в Keychain), refresh token в Keychain/EncryptedSharedPreferences. Silent refresh: при получении 401 — автоматический запрос нового access token с refresh token. Если refresh token истёк — принудительный логин.
Rotation refresh tokens: каждый обмен refresh token на access token выдаёт новый refresh token. Старый инвалидируется. Если старый refresh token попытался использоваться — компрометация, все токены пользователя отзываются.
| Тип токена |
Время жизни |
Где хранить |
Действие при компрометации |
| Access token |
15–60 минут |
In‑memory |
Истекает быстро, ущерб минимален |
| Refresh token |
30–90 дней |
Keychain/Keystore |
Ротация + отзыв всех токенов |
Что входит в работу
При заказе модуля аутентификации мы предоставляем:
- Исходный код модуля авторизации (Swift/Kotlin) с интеграцией выбранных методов.
- Документацию по архитектуре и схеме токенов.
- Настроенный PKCE‑флоу для OAuth 2.0.
- Интеграцию Sign in with Apple и Google Sign-In по вашим client_id.
- Конфигурацию биометрии с правильными protection‑флагами.
- Инструкцию по деплою и тестированию (TestFlight, Firebase App Distribution).
- Чек‑лист для прохождения ревью App Store и Google Play.
Сроки и стоимость
Реализация базовой аутентификации (email + пароль + JWT) занимает от 1 до 2 недель. Добавление OAuth, биометрии и 2FA — ещё 1–3 недели. Итоговая стоимость рассчитывается после аудита вашего проекта. Получите консультацию — мы оценим сложность и предложим оптимальный стек.
Типичные ошибки (и как их избежать)
- Хранение токенов в UserDefaults / SharedPreferences — читаются без root на рутованных устройствах. Решение: Keychain / Keystore.
- Отсутствие certificate pinning в high‑security приложениях — MITM через корпоративный proxy. Решение: добавляем pinning в URLSession или OkHttp.
- Хранение секретов в Info.plist или BuildConfig — декомпилируются тривиально. Решение: использовать Keychain или серверную конфигурацию.
- OAuth через WKWebView / WebView вместо системного браузера — rejection App Store + security risk. Решение: ASWebAuthenticationSession / Custom Tabs.
- Неправильный kSecAttrAccessible — токен с kSecAttrAccessibleAlways не требует разблокировки устройства. Решение: WhenUnlockedThisDeviceOnly.
Чек‑лист безопасности аутентификации
- [ ] Refresh token в Keychain/Keystore с protection класса
- [ ] PKCE включён в OAuth flow
- [ ] Certificate pinning настроен (если требуется)
- [ ] Биометрия привязана к текущему набору данных
- [ ] Доступ к токену заблокирован при изменении биометрии
- [ ] 2FA включена для критичных операций
- [ ] Ротация refresh tokens активна
- [ ] Логирование неудачных попыток без хранения чувствительных данных
- [ ] Соблюдены Guideline 4.8 и 5.1.1 App Store
Мы реализовали безопасную аутентификацию для 30+ проектов за 5 лет работы. Гарантируем соответствие требованиям платформ и лучшим практикам (OAuth 2.0 + PKCE, Keychain, Keystore). Закажите разработку модуля аутентификации — разберём уязвимости и предложим решение под ваш бюджет. Получите консультацию через форму на сайте.