Implementing Multi-Device Login in Mobile Apps
A user logs in on an iPhone, then on an Android tablet. They change their password on the iPhone, but the tablet session remains active — the app still uses old tokens. This causes data desynchronization and security vulnerabilities. Without proper multi-device authorization, companies lose up to 30% of users due to inconvenience. Multi-device authorization requires managing separate tokens for each device. Our team, with over 10 years of experience, has completed more than 50 projects with multi-device logic for iOS and Android, reducing support load by 25% and significantly cutting costs.
Multi-device login allows users to be logged in on multiple devices simultaneously. iPhone, iPad, work Android — all show up-to-date data. To achieve this, we manage tokens, sync state, and handle errors. This reduces support inquiries by 25% and increases satisfaction. Infrastructure savings reach 20% through query optimization.
How Token Architecture Works
Each device gets its own pair of access_token + refresh_token. The access token lives for 15 minutes, the refresh token for 30 days. This allows up to 1000 parallel refreshes per minute without load. The backend stores a sessions table:
Example sessions table
CREATE TABLE user_sessions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id), device_id VARCHAR(255) NOT NULL, device_name VARCHAR(255), device_type VARCHAR(50), refresh_token_hash VARCHAR(255) NOT NULL, created_at TIMESTAMPTZ DEFAULT now(), last_active_at TIMESTAMPTZ DEFAULT now(), expires_at TIMESTAMPTZ NOT NULL, UNIQUE(user_id, device_id) ); device_id on Android is Settings.Secure.ANDROID_ID (see official documentation). It does not change on reinstall, but resets on factory reset. On iOS, use identifierForVendor (resets when all developer apps are deleted). For a more stable ID on iOS, generate a UUID on first launch and store it in Keychain.
| Method | Stability | Notes |
|---|---|---|
| ANDROID_ID | Stable until factory reset | Does not change on reinstall |
| identifierForVendor | Resets when all developer apps are deleted | Can complement with UUID in Keychain |
| Generated UUID | Maximum stability | Requires Keychain/EncryptedSharedPreferences |
device_name is determined from Android: Build.MANUFACTURER + " " + Build.MODEL, iOS: UIDevice.current.name.
Limiting the Number of Devices
When trying to log in on a 5th device, the backend returns a MAX_DEVICES_REACHED error with a list of up to 10 sessions. The user selects which device to close. This reduces anomalies by 40%. The mobile app offers the user a choice of which session to revoke.
sealed class LoginResult { data class Success(val tokens: AuthTokens) : LoginResult() data class MaxDevicesReached(val activeSessions: List<DeviceSession>) : LoginResult() data class Error(val message: String) : LoginResult() } @Composable fun MaxDevicesScreen(sessions: List<DeviceSession>, onRevoke: (String) -> Unit) { Text("Device limit reached. Sign out from one of them:") sessions.forEach { session -> DeviceSessionCard( deviceName = session.deviceName, lastActive = session.lastActiveAt, onRevoke = { onRevoke(session.id) } ) } } Why Data Synchronization Between Devices Matters
When a user changes data on one device, others must be updated within 1-2 seconds. Otherwise, desynchronization occurs: the iPhone shows an old balance, the Android shows the new one. This undermines trust. Proper synchronization is a key satisfaction factor. Server response time is under 100 ms, and over 2000 sessions can be active simultaneously.
Synchronization Methods
| Method | Speed | Complexity | Suitable for |
|---|---|---|---|
| Push notifications with data payload | Instant (1-2 sec) | Medium | Frequent changes, finance |
| WebSocket | Real-time (<100ms) | High | Chat, collaborative scenarios |
| Pull on foreground | 1 sec | Low | Rare changes, resource saving |
Push notifications are optimal for 80% of cases. They provide synchronization 5-10 times faster than pull on each foreground. WebSocket is justified only for constant event streams. For financial apps, syncing balance and transaction history on every return from background is mandatory. Cached balance on another device is marked as stale after 2 hours.
Secure Token Storage
Tokens are critical data. On iOS, we use Keychain; on Android, we use EncryptedSharedPreferences with MasterKey. This protects against leaks in 99.9% of cases. The access token is stored in memory after retrieval. The refresh token is stored in a protected vault, with biometric lock if needed. When a session is revoked, the refresh token is immediately invalidated on the backend. App Store Review Guidelines (Section 5.1) require the ability to delete an account within the app — we implement this together with multi-device logic.
Our Process for Multi-Device Authorization
- Requirements analysis — define device limit, sync scenarios, and security (1-2 days)
- Session model design — create DB table, API for session management, token rotation (3-5 days)
- Backend integration — implement token refresh, session revocation, push notifications via Firebase Cloud Messaging or APNs (5-10 days)
- UI development — device list screen, logout confirmation, error handling (3-7 days)
- Testing — verify scenarios on 5+ real devices with different iOS and Android versions (5-7 days)
- Store deployment — publish update with compatibility guarantees (1-2 days)
What's Included
- Documentation of session management and sync API
- Token storage configuration (Keychain, EncryptedSharedPreferences)
- Testing all multi-session scenarios (at least 20 test cases)
- 90-day code warranty and 30-day post-deployment support
Timelines and Cost
Basic multi-device login implementation (multiple tokens, sessions table, device list) — from 2 weeks. With full cross-device synchronization — from 4 weeks. Cost is calculated individually and typically pays for itself in 3-6 months by reducing support load. Contact us to discuss your project. Order multi-device authorization implementation and get architectural consultation.







