Active Sessions Management on Multiple Devices
Sessions management screen — standard security practice for mobile apps with sensitive data. User sees login sources from different devices and can force-close any session. Telegram, Google, banking apps — all implement this.
What to Show User
For each active session, provide minimal context to identify device:
- Device name and platform ("iPhone 15 Pro, iOS 17.4")
- Approximate last login location via IP (GeoIP2 / ipapi)
- Last activity date and time
- Current device marked separately
data class DeviceSession(
val sessionId: String,
val deviceName: String,
val deviceType: DeviceType, // IOS, ANDROID, WEB
val location: String?, // "Moscow, Russia"
val lastActiveAt: Instant,
val createdAt: Instant,
val isCurrentDevice: Boolean
)
Identify current device: when fetching sessions list, backend compares device_id from JWT with device_id each session. Current device can't be closed from this screen — only via explicit logout.
Sessions Screen UI
@Composable
fun ActiveSessionsScreen(
sessions: List<DeviceSession>,
onRevokeSession: (String) -> Unit,
onRevokeAll: () -> Unit
) {
LazyColumn {
item {
Text(
"Active Sessions",
style = MaterialTheme.typography.headlineSmall
)
}
items(sessions, key = { it.sessionId }) { session ->
SessionCard(
session = session,
onRevoke = if (session.isCurrentDevice) null
else {{ onRevokeSession(session.sessionId) }}
)
}
if (sessions.count { !it.isCurrentDevice } > 1) {
item {
TextButton(onClick = onRevokeAll) {
Text("Sign out from all other sessions")
}
}
}
}
}
Session Revocation
Close session: backend invalidates refresh_token (deletes from table or marks revoked). Device with revoked session on next API request or token refresh gets 401. Mobile handles 401 — redirects to login screen and clears local data.
For immediate effect (user fears compromise), need more aggressive mechanism: on session revocation backend sends silent push to that device with immediate logout command. On Android — FCM data message with action: "force_logout". On iOS — APNs background notification with content-available: 1.
// Firebase Function: on session revocation
async function revokeDeviceSession(sessionId: string, targetDeviceToken: string) {
await db.collection('sessions').doc(sessionId).update({ revoked: true });
await admin.messaging().send({
token: targetDeviceToken,
data: {
action: 'force_logout',
reason: 'session_revoked'
},
android: { priority: 'high' }
});
}
Notifications on New Login
Security practice: on login from new device, send push to other active user devices: "Logged in on Samsung Galaxy S24 from Moscow. Was that you?" With "No, close this session" button.
Standard at banks and fintech apps. Implementation: after creating new session, backend iterates other user's fcm_token and sends notification.
Sessions screen + new login notifications + force logout via push — 2–3 weeks. Cost estimated individually.







