TL;DR
Securely handle user logins on mobile apps using tokens instead of passwords directly. This guide covers storing tokens, refreshing them automatically, and protecting against common security issues.
1. Understanding Token Authentication
Instead of sending usernames and passwords with every request, token authentication works like this:
- The user logs in (username/password).
- Your server verifies the credentials.
- If correct, the server creates a unique token for that user.
- This token is sent back to the app.
- For every subsequent request, the app sends the token instead of login details.
Tokens have an expiry date, so they need refreshing.
2. Secure Token Storage
Where you store the token is critical for security. Avoid storing it in plain text!
- iOS: Use Keychain Services. This is a secure storage container provided by Apple.
- Android: Use Android Keystore System. Similar to Keychain, this provides hardware-backed security where possible.
Don’t store tokens in shared preferences or local files without encryption.
3. Initial Token Retrieval
When a user logs in, your app sends their credentials to the server (usually via HTTPS). The server responds with a token (often as JSON).
// Example response from server
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkJWT..." }
Store this token securely using the methods in Step 2.
4. Adding Tokens to Requests
Every time your app makes a request to your server, include the token in the Authorization header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkJWT...
Most networking libraries (e.g., Retrofit for Android, URLSession for iOS) allow you to easily set headers.
5. Token Refreshing
Tokens expire for security reasons. Implement a refresh mechanism:
- Check Expiry: Before making a request, check if the token is about to expire (e.g., within 10 minutes).
- Refresh Request: If expiring soon, send a request to your server for a new token. This usually requires a special ‘refresh’ endpoint.
- Automatic Refresh: Ideally, refresh tokens in the background before they expire. Use background tasks or scheduled jobs provided by the mobile OS.
The refresh endpoint typically needs a refresh token (a long-lived token issued alongside the main token). Store this refresh token securely too!
6. Handling Token Errors
- Invalid Token: If the server rejects the token, redirect the user to the login screen.
- Refresh Failed: If refreshing fails (e.g., invalid refresh token), also redirect to login.
Clear both the main token and the refresh token from secure storage when an error occurs.
7. Security Considerations
- HTTPS Only: Always use HTTPS for all communication.
- Token Size: Keep tokens reasonably short to reduce transmission overhead.
- Server-Side Validation: The server must validate every token on every request. Don’t trust the app!
- Protect Refresh Tokens: Treat refresh tokens as highly sensitive data. Limit their scope and lifespan.
- Revocation: Implement a mechanism to revoke tokens (e.g., when a user logs out or changes their password).

