Авторизация
Обзор
JWT-авторизация через saas-api с поддержкой email/password и Google OAuth. Токены хранятся в expo-secure-store.
SessionProvider
src/features/auth/context/session-provider.tsx — контекстный провайдер авторизации. Оборачивает всё приложение в root layout.
Состояние сессии
| Поле | Тип | Описание |
|---|---|---|
session | AuthTokens | null | Access + refresh токены |
user | User | null | Текущий пользователь |
isLoading | boolean | Начальная загрузка |
Хук useSession()
typescript
const { session, user, isLoading, signIn, signUp, signInWithGoogle, signOut } = useSession();Потоки авторизации
Email/Password
signIn(email, password)
→ saasApi.signIn()
→ saasApi.getMe()
→ Сохранение токенов в SecureStore
→ Кэширование user в SecureStore
→ Установка userId в Analytics
→ Редирект в (app)Регистрация
signUp(email, password)
→ saasApi.signUp()
→ saasApi.getMe()
→ Сохранение сессии
→ Редирект на verify-code (если не верифицирован)Google OAuth
signInWithGoogle()
→ saasApi.getGoogleAuthUrl()
→ WebBrowser.openAuthSessionAsync(url)
→ Парсинг callback URL для токенов
→ saasApi.handleOAuthCallback(tokens)
→ saasApi.getMe()
→ Сохранение сессии
→ Редирект в (app)Управление токенами
Хранение
- Access и refresh токены —
expo-secure-store(зашифрованное хранилище) - Данные пользователя —
SecureStoreкак JSON (fallback при загрузке)
Auto-refresh
- Токен обновляется за 5 минут до истечения
- При 401 — автоматический refresh + повтор запроса
- При повторном 401 после refresh — принудительный логаут
Lifecycle
- Запуск приложения: загрузка токенов из SecureStore → проверка валидности → запрос свежих данных пользователя
- Во время работы: автоматический refresh, retry на 401
- Логаут: очистка токенов → очистка кэша → сброс stores → отключение WebSocket
- Forced logout: триггерится через
saasApi.onUnauthorized()callback
Верификация email
Пользователи с verificationStatus: 'NotVerified' перенаправляются на экран verify-code. После верификации — доступ к полному приложению.
Навигационные гарды
Root layout проверяет состояние и перенаправляет:
| Состояние | Редирект |
|---|---|
| Нет сессии | (auth)/login |
| Не верифицирован | (auth)/verify-code |
| Нет компаний | Экран создания компании |
| Всё ок | (app)/(tabs) |