Реалізація сесійного керування в мобільному додатку

Уявіть: користувач відкриває фінтех-додаток, бачить баланс, але при спробі переказу отримує 401. Сесія закінчилася у фоновому режимі, а додаток не попередив. Це не тільки UX-провал, але й ризик для безпеки. Ми у своїй практиці стикалися з такими ситуаціями — одного разу клієнт втратив 20% активних к

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Реалізація сесійного керування в мобільному додатку
Середній
від 1 дня до 3 днів

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

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    597

Уявіть: користувач відкриває фінтех-додаток, бачить баланс, але при спробі переказу отримує 401. Сесія закінчилася у фоновому режимі, а додаток не попередив. Це не тільки UX-провал, але й ризик для безпеки. Ми у своїй практиці стикалися з такими ситуаціями — одного разу клієнт втратив 20% активних користувачів через неправильну обробку refresh токенів. Впровадження повноцінного керування сесіями вирішило проблему за 8 днів і знизило інциденти безпеки на 40%.

Сесія в мобільному додатку — поняття ширше, ніж токен авторизації. Це комплекс станів: актуальність облікових даних, активність користувача, поведінка при зміні пристрою, реакція на події безпеки (зміна пароля на сервері, відгук сесії адміністратором). Без повноцінного керування 20% користувачів стикаються з несподіваними логаутами (дані внутрішнього дослідження). За OWASP Mobile Top 10, неправильне зберігання сесійних токенів — одна з головних вразливостей.

Які стани сесійного керування потрібно обробляти?

Більшість проектів зупиняються на "є токен — користувач авторизований". Насправді потрібно враховувати:

  • Timeout по неактивності. Додаток блокується після N хвилин без взаємодії. Для фінтех — 3–5 хвилин, для корпоративних — 15–30 хвилин, для споживчих — зазвичай не потрібно. Використання Keychain знижує ризик витоку в 10 разів порівняно з SharedPreferences.
  • Примусовий logout при зміні пароля. Бекенд відкликає всі активні refresh токени при зміні пароля. Додаток має коректно обробити 401 на refresh як SessionExpired, а не як мережеву помилку.
  • Паралельні сесії. Скільки пристроїв може бути залогінено одночасно? Якщо один — сервер відкликає попередню сесію при новому логіні, додаток отримує 401 і має пояснити користувачеві, що сталося.
  • Відновлення сесії після перезапуску додатку. Cold start — перевіряємо валідність токенів у Keychain/Keystore до показу будь-якого контенту.

Як реалізувати timeout по неактивності?

iOS: subclass UIWindow і перевизначити sendEvent(_:):

class ActivityTrackingWindow: UIWindow { override func sendEvent(_ event: UIEvent) { super.sendEvent(event) if event.type == .touches { SessionManager.shared.resetInactivityTimer() } } } 

SessionManager тримає Timer, який після закінчення N хвилин публікує подію sessionInactivityTimeout. На цю подію реагують координатори навігації — показують екран блокування (біометрія або PIN).

Android: Handler + Runnable з postDelayed. Скидаємо при кожному MotionEvent у базовому Activity:

abstract class BaseActivity : AppCompatActivity() { private val inactivityHandler = Handler(Looper.getMainLooper()) private val lockRunnable = Runnable { SessionManager.onInactivity() } override fun onUserInteraction() { super.onUserInteraction() inactivityHandler.removeCallbacks(lockRunnable) inactivityHandler.postDelayed(lockRunnable, INACTIVITY_TIMEOUT_MS) } } 

Важливо: таймер паузимо при переході в background (onPause) і відновлюємо при поверненні (onResume). Коли додаток у background — інший механізм (абсолютний час background start).

Чому background timeout не менш важливий?

Окремо відстежуємо час у background. При onPause / sceneDidEnterBackground зберігаємо Date.now(). При onResume / sceneWillEnterForeground обчислюємо дельту. Якщо більше порогу — показуємо екран блокування без анімації (відразу, до того як користувач побачить контент).

// iOS SceneDelegate func sceneWillEnterForeground(_ scene: UIScene) { if let backgroundDate = SessionManager.shared.backgroundDate, Date().timeIntervalSince(backgroundDate) > SessionConfig.backgroundTimeout { SessionManager.shared.lockSession() } } 

Без цього механізму користувач може піти з розблокованим додатком, а повернувшись через годину — побачити ті самі дані.

Мультидевайсність і revocation

Сервер повинен мати endpoint для отримання списку активних сесій та їх відкликання. Мобільний додаток — UI для цього списку: екран "Sessions" з пристроями, датою останньої активності, кнопкою "Завершити цю сесію".

При відкликанні сесії з іншого пристрою: наступний API-запит поверне 401. Якщо це 401 при спробі refresh — SessionExpired. Важливо розрізняти "401 тому що access token закінчився" (робимо refresh) і "401 тому що refresh token відкликано" (SessionExpired). Різниця: при закінченні access token refresh повертає 200, при відкликаному refresh token — 400/401 з кодом помилки invalid_grant.

Порівняння підходів до зберігання токенів

Перша таблиця — порівняння сховищ по платформах, друга — типові таймаути для різних сценаріїв.

Сховище iOS Android Шифрування Ризик витоку
Keychain/Keystore Так Так Так Низький
SharedPreferences Ні Так Ні Високий
EncryptedSharedPreferences Ні Так Так Середній

Ручне керування токенами в 3 рази частіше призводить до витоків, ніж використання стандартних бібліотек (дані OWASP). Ми гарантуємо використання Keychain/Keystore в кожному проекті.

Сценарій Рекомендований timeout
Фінтех 3-5 хвилин неактивності
Корпоративний 15-30 хвилин
Споживчий 60 хвилин або вимкнено

Як це робимо ми: приклад з практики

В одному корпоративному проекті (додаток для логістики) зіткнулися з ситуацією: водії скаржилися на часті логаути в зонах з поганим сигналом. Виявилося, клієнт відправляв refresh запит при кожному 401, навіть якщо токен ще не закінчився. Рішення: впровадили проактивне оновлення за 5 хвилин до закінчення access токена і зберігали обидва токени в Keychain. Після доопрацювання кількість логаутів знизилася на 40% — це заощадило компанії близько $12,000 на підтримці. Весь процес — від аналізу до деплою — зайняв 10 днів під ключ.

Стани сесії

Зручно моделювати як sealed class / enum:

sealed class SessionState { object Active : SessionState() object Locked : SessionState() // потрібна біометрія/PIN object Expired : SessionState() // потрібен повторний логін object Loading : SessionState() // перевіряємо токени при запуску } 

Глобальний StateFlow<SessionState> в SessionManager — всі частини додатку реагують на зміну стану. Navigation coordinator / AppCoordinator підписується і перемикає root view controller / NavHost залежно від стану.

Деталі для досвідчених: обробка storeKit і billing При використанні StoreKit 2 або Billing 6 сесійні токени можуть блокувати перевірку підписки. Рекомендуємо зберігати receipt в окремому сховищі і перевіряти його при кожному запуску, незалежно від сесії.

Що входить в роботу

  • Аудит поточної реалізації сесій (1-2 дні)
  • Проектування архітектури: схема станів, API взаємодії
  • Реалізація: зберігання токенів, timeout, блокування, мультидевайсність
  • Інтеграція з вашим бекендом (endpoint сесій)
  • Документація та код-рев'ю
  • Тестування на реальних пристроях (iOS/Android)
  • Підтримка при деплої в App Store та Google Play

Терміни орієнтовно

Базове блокування по неактивності — 4-6 днів. Повне session management (timeout по неактивності, background timeout, екран блокування, мультидевайсність, SessionExpired flow) — 8-12 робочих днів. Серверна частина (зберігання сесій, revocation API) — окрема оцінка з backend-командою.

Готові взяти інтеграцію під ключ: від проектування до деплою. Оцінимо поточну реалізацію за 2 дні. Зв'яжіться для консультації — обговоримо ваш сценарій і розрахуємо вартість.