Privacy

    What to clear on logout in a mobile app: the full list

    A phone after logout with a checklist of tokens, caches, database files and push registrations being removed.

    A logout button that only hides the account screen leaves a surprising amount behind: tokens in secure storage, cached API responses, a local database full of the previous user's data, images in the cache folder, a push token still registered to the old account, and a session the server still considers valid. On a personal phone that is untidy. On a shared tablet, a phone handed to a family member, or a device being sold, it is a privacy failure. Getting logout right is mostly a checklist, and the items on it are easy to miss because nobody tests logout as carefully as login.

    Short answer

    A complete logout does two things: it ends the session on the server, and it removes the account's data from the device. On the server, revoke the refresh token and any active sessions. On the device, delete tokens from the Keychain or Keystore, clear the local database and caches that belong to the account, remove downloaded files, unregister or reassign the push token, reset analytics identifiers tied to the user, and clear in-memory state. Remember that iOS Keychain items can survive an app uninstall, so a reinstall should not quietly restore the previous session.

    Why logout gets less attention than login

    Login is tested on every build because nothing works without it. Logout is tested once, when the button is added, by checking that the login screen appears afterwards. That check passes whether or not anything was actually removed.

    Meanwhile, apps accumulate state over time. A networking library caches responses, an image loader keeps a disk cache, a database grows new tables for new features, an analytics SDK assigns a user ID, a push service registers a token. Each was added by someone thinking about their feature, not about the account ending. The OWASP Session Management Cheat Sheet treats logout as a server-side invalidation requirement first, and the device-side clean-up is the mobile-specific half.

    End the session on the server first

    Deleting a token from the device does not make it invalid. If the token was copied, through a backup, a compromised device, a log or a proxy, it keeps working until it expires. Logout should call the backend to revoke the refresh token and, for sensitive apps, end the session everywhere the user chooses. This is the weakness described in CWE-613, insufficient session expiration.

    If the network call fails, still clear the device and retry the revocation later, or let short access token lifetimes limit the window. The post on mobile session management covers token lifetimes and revocation in more depth.

    What to clear on the device

    ItemWhere it livesWhat happens if leftHow to clear
    Access and refresh tokensKeychain, Keystore, secure storageNext user or attacker resumes the sessionDelete items explicitly
    Local databaseSQLite, Room, Core Data, RealmPrevious user's data visible or syncedDelete or wipe account tables
    HTTP response cacheURL cache, OkHttp cacheOld responses served to the next userClear the cache
    Image and file cachesCache and documents foldersPhotos and documents remain readableDelete account files
    Push token registrationYour backend and push providerNotifications go to the wrong personUnregister or reassign server-side
    Analytics and crash user IDsSDK storageNew activity attributed to the old userCall the SDK reset method
    In-memory stateView models, stores, singletonsOld data flashes on the next screensReset app state or restart the root
    Preferences tied to the accountUserDefaults, SharedPreferencesSettings and drafts leak across accountsRemove account-scoped keys

    Each row is a separate piece of code, which is why a single central logout function that calls every clean-up step is worth having. New features then add their clean-up to that function rather than relying on someone remembering.

    Tokens and the Keychain uninstall surprise

    On iOS, items stored in the Keychain can persist after the app is deleted and be readable again if the app is reinstalled. This behaviour has existed for years and catches teams in two ways. A user who deletes the app to sign out, a common habit, finds themselves signed straight back in after reinstalling. And a device passed to someone else can carry the previous user's tokens into a fresh install.

    The fix is to detect a fresh install, for example with a flag in regular app storage, which is removed on uninstall, and to clear Keychain items when that flag is missing. Libraries such as Expo SecureStore use the Keychain on iOS, so the same consideration applies to React Native apps.

    On Android, app data including Keystore-protected keys is removed on uninstall, but Auto Backup can restore files on reinstall or on a new device unless sensitive files are excluded. Tokens and account databases should be excluded from backup.

    Local data and caches

    The local database is usually the largest store of personal data on the device. On logout, either delete the database file entirely or clear every table that holds account data, and do the same for any encrypted store and its key. The post on encrypting local databases covers key handling, and the key should be deleted along with the data.

    HTTP caches are easy to forget because they are managed by the networking layer. On iOS, URLCache can hold full responses on disk; on Android, OkHttp and similar clients keep their own caches. Clear them on logout, and consider not caching authenticated responses at all, as discussed in the post on NSURLCache and sensitive responses.

    Downloaded files, generated PDFs, cached images and voice notes live in the app's cache and documents directories. Delete the account's files explicitly rather than trusting the system to clear caches eventually.

    Push notifications

    If the push token stays registered to the old account, the next person to sign in on that device may receive the previous user's notifications, and a device that was sold keeps receiving them. On logout, tell your backend to remove the association between the device token and the account. Firebase's guidance on managing registration tokens covers keeping that mapping accurate, and on iOS the app can also unregister for remote notifications if it should stop receiving them entirely.

    Analytics, crash reporting and other SDKs

    Most analytics and crash reporting SDKs let you set a user identifier, and most have a reset or logout call. Without it, the next user's activity is attributed to the previous account, which is a data accuracy problem and, under privacy law, can be a data protection problem. Add each SDK's reset call to the central logout function, and review the list whenever a new SDK is added.

    Account switching and shared devices

    Apps used on shared devices, such as staff tablets, kiosks and family phones, need logout to be complete every time, and they often need a fast account switch too. The safest pattern is to treat each sign-in as a fresh start: no data from the previous account is reused, even if the same person signs back in a minute later. Where speed matters, separate account-scoped data clearly from device-level settings so the clean-up can remove one without touching the other.

    Logout on account deletion and password change

    Account deletion is logout with stricter requirements. Apple requires apps that support account creation to offer account deletion in the app, and when an account is deleted, every device-side item in the list above should be removed along with the server-side data, not just the session. A deleted account that still shows cached messages on the device is a visible failure in exactly the moment the user is paying attention.

    A password change or a reported compromise should end other sessions as well. Offer the user a choice to sign out everywhere, revoke all refresh tokens server-side when they accept it, and make sure each device clears its local state the next time it receives a rejected token rather than continuing to show cached data. The same central logout function can run in that case, triggered by the server's response instead of the button.

    Background and offline cases

    Logout often happens at awkward moments: while an upload is running, while offline, or while a background sync is mid-way. Cancel queued requests that carry the old token, stop background tasks tied to the account, and if the device is offline, clear the local state immediately and queue the server revocation for when connectivity returns. Showing the login screen while a background job continues to write the previous user's data into the database is a common bug that inspection after logout reveals quickly.

    Web views and cookies

    Apps that show account pages in a web view, for example a help centre, a checkout or a settings page served by the website, also hold a cookie store. Clearing native tokens does nothing to the web view's session cookies, so the next user who opens that screen may find the previous user signed in on the web side. Clear the web view's cookies and website data on logout, and if the app uses an external browser session for sign-in, end that session on the server as well, since the app cannot clear the system browser's cookies itself.

    Widgets, extensions and shared containers

    On iOS, app extensions and widgets often read data from an App Group container shared with the main app. If logout clears only the main app's storage, a home screen widget can keep showing the previous user's balance, messages or tasks. Clear the shared container and reload widget timelines as part of logout. Android home screen widgets and notification channels deserve the same check.

    A single function, tested in CI

    Put every clean-up step behind one function and cover it with an automated test that signs in, populates each store, logs out and asserts each store is empty. That test fails the day someone adds a new cache or SDK without adding its clean-up, which is exactly the regression manual testing misses. Pair it with a periodic manual inspection on a real device, since some stores, such as the Keychain and widget timelines, behave differently outside a test environment.

    Review the test whenever a dependency is added, because new SDKs are the most common source of state nobody thought to clear. A logout that was complete last quarter can be incomplete today without any change to the logout code itself.

    Testing logout properly

    A logout test should prove absence, not just show the login screen. Sign in, use every major feature so data is cached, then log out and inspect the app container on a test device: secure storage items, database files, caches and preferences. Sign in as a different user and check that nothing from the first account appears, including in notifications. Then delete and reinstall the app and confirm it does not resume the old session.

    An automated pass over the built artifact, such as PTKD.com, flags the build-level settings around this, such as backup configuration and insecure storage APIs used for tokens; the runtime behaviour of logout itself needs the device inspection described above, since it depends on code paths rather than build settings. The OWASP MASVS authentication requirements and privacy requirements set the standard reviewers will use.

    What to take away

    Logout is two jobs: revoke the session on the server and remove the account from the device. On the device that means tokens, the local database and its key, HTTP and file caches, account preferences, push token registration, analytics identifiers and in-memory state, all cleared from one central function that new features extend. Handle the iOS Keychain surviving uninstall and Android backups restoring files, and test logout by inspecting what remains rather than by watching the login screen appear.

    • #logout
    • #session management
    • #keychain
    • #push notifications
    • #local data
    • #privacy

    Frequently asked questions

    What should a mobile app clear on logout?
    Revoke the session on the server, then delete tokens from the Keychain or Keystore, clear the local database and its encryption key, empty HTTP and file caches, remove account preferences and downloaded files, unregister or reassign the push token, reset analytics user identifiers and reset in-memory state. Do it from one central function so new features add their clean-up there.
    Is deleting the token on the device enough to log out?
    No. A deleted token is gone from that device, but a copy taken earlier through a backup, log, proxy or compromised device keeps working until it expires. Logout should call the backend to revoke the refresh token and end the session, and access tokens should be short-lived so the remaining window is small.
    Why does my iOS app stay logged in after reinstalling?
    Because Keychain items can persist after an app is deleted and become readable again on reinstall. If tokens live in the Keychain, the reinstalled app finds them and resumes the session. Detect a fresh install with a flag in regular app storage, which uninstall removes, and clear Keychain items when the flag is missing.
    Do push notifications need handling on logout?
    Yes. If the device's push token stays associated with the old account on your backend, the next person to sign in, or the next owner of the device, can receive the previous user's notifications. Remove or reassign the token-to-account mapping server-side on logout, and unregister entirely when the app should stop receiving pushes.
    When is a partial logout acceptable?
    Rarely, and only for data that is not personal, such as downloaded public content or device-level settings like theme or language. Anything tied to the account, including messages, history, documents, tokens and identifiers, should be removed. Apps used on shared devices should treat every logout as a full reset.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free