Реализация авторизации через JWT-токены в мобильном приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1735 услуг
Реализация авторизации через JWT-токены в мобильном приложении
Средний
~1 день
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    495

Реализация авторизации через JWT-токены в мобильном приложении

JWT — это формат токена, не протокол авторизации. Это важно понимать, потому что многие проекты строят собственный "JWT auth" без понимания того, что именно они защищают и от чего.

Типичная картина: бэкенд генерирует JWT, подписывает HS256 (HMAC-SHA256), мобильное приложение получает токен, кладёт в UserDefaults и отправляет в заголовке Authorization: Bearer. Работает. Но вопрос в том, насколько безопасно.

Проблема хранения и где она бьёт

UserDefaults (iOS) и SharedPreferences (Android) — это plaintext хранилища. На iOS без jailbreak добраться до них сложно, но iOS backup в iTunes/iCloud их включает. Пользователь бэкапит устройство на компьютер с macOS — ключи от бэкапа без пароля хранятся в открытом виде. Через idevicebackup2 и специализированные утилиты JWT можно извлечь за минуты.

Правило простое: JWT хранится только в Keychain (iOS) или Android Keystore / EncryptedSharedPreferences (Android). Никаких UserDefaults, AsyncStorage в React Native без дополнительного шифрования.

В React Native это особенно больно — AsyncStorage по умолчанию plaintext. Библиотека react-native-keychain решает проблему для iOS и Android, оборачивая платформенные хранилища.

Верификация на клиенте: что проверять и что нет

Мобильное приложение может декодировать JWT и читать claims — для отображения имени пользователя, проверки ролей в UI, определения времени истечения для проактивного refresh. Но верифицировать подпись на клиенте бессмысленно, если JWT подписан симметричным ключом (HS256) — клиент не должен знать этот ключ.

Что клиент должен проверять:

  • exp — не истёк ли токен (с небольшим запасом, ~30 секунд, для clock skew)
  • iss — ожидаемый издатель
  • aud — токен предназначен для нашего приложения

Если сервер использует RS256 или ES256 (асимметричный алгоритм) — клиент может верифицировать подпись через публичный ключ. Это имеет смысл для offline-сценариев, когда нет сети, но надо проверить токен локально.

Библиотеки: JWTDecode.swift (iOS), java-jwt от Auth0 или nimbus-jose-jwt (Android), jwt-decode (React Native).

Refresh и silent auth

Access token живёт 15–60 минут. Refresh token — дни/недели. Автоматическое обновление — обязанность HTTP-клиента, не бизнес-логики.

На iOS c URLSession: кастомный URLSessionTaskDelegate или middleware-паттерн. В Alamofire — RequestInterceptor с методами adapt и retry. На Android с Retrofit — Authenticator (вызывается при 401) или Interceptor (проверяет exp до запроса).

// Android Retrofit Authenticator
class TokenAuthenticator(private val tokenRepo: TokenRepository) : Authenticator {
    override fun authenticate(route: Route?, response: Response): Request? {
        if (response.code != 401) return null
        val newToken = runBlocking { tokenRepo.refreshToken() } ?: return null
        return response.request.newBuilder()
            .header("Authorization", "Bearer $newToken")
            .build()
    }
}

Важна защита от параллельных refresh-запросов. Если пять запросов одновременно получили 401 — пять попыток refresh. Правильно: Mutex (Kotlin) / NSLock (Swift) или async let с actor (Swift Concurrency). Первый поток делает refresh, остальные ждут результата.

// iOS — actor для serialized refresh
actor TokenRefreshActor {
    private var refreshTask: Task<String, Error>?

    func refreshIfNeeded(using service: AuthService) async throws -> String {
        if let task = refreshTask { return try await task.value }
        let task = Task { try await service.refresh() }
        refreshTask = task
        defer { refreshTask = nil }
        return try await task.value
    }
}

Revocation и logout

JWT stateless по природе — нельзя "отозвать" токен без дополнительной инфраструктуры. Короткий exp + refresh token rotation — основная защита. При logout:

  1. Удаляем токены из Keychain/Keystore.
  2. Вызываем /auth/logout на сервере → сервер инвалидирует refresh token в базе.
  3. Если сервер ведёт blocklist — access token тоже инвалидируется немедленно.

Пункт 2 и 3 — серверная работа. Но мобильная сторона обязана вызвать logout endpoint, даже если пользователь в оффлайне (ставим в очередь через WorkManager / BackgroundTasks).

Сроки

JWT auth с нуля: хранилище, interceptor для attach/refresh, logout, unit-тесты — 4–7 рабочих дней. Если нужна интеграция с существующим бэкендом и согласование формата claims — плюс 2–3 дня на синхронизацию с backend-командой.