A new Wipro mobile application requires robust user authentication and authorization. How would a Mobile Developer design a secure token-based system, considering mobile-specific challenges like offline access and sensitive data storage?
Designing a secure token-based authentication and authorization system for a new mobile application involves implementing a robust OAuth 2.0 flow, typically utilizing JSON Web Tokens (JWTs). The core principle is to issue a short-lived access token for API requests and a longer-lived refresh token for obtaining new access tokens without requiring the user to re-enter credentials. Upon successful login with credentials, the authentication server issues both tokens. The access token is then included in the Authorization header of subsequent API requests to the resource server for authorization.
Mobile-Specific Authentication Challenges
Mobile environments pose unique challenges for token management. Secure storage is paramount; access and refresh tokens must be stored in platform-specific secure storage mechanisms, like iOS Keychain or Android Keystore, which protect them from other applications and unauthorized access. Tokens should never be stored in plain text in user defaults or shared preferences. Implementing biometrics (Face ID/Touch ID) can enhance user experience for re-authentication or transaction signing, without exposing the underlying token. For offline access, the application can locally validate a cached token’s expiry and grant access to cached data, but critical operations always require an active, validated token. Certificate pinning should also be implemented to prevent man-in-the-middle attacks by ensuring the app only communicates with trusted servers.
Best practice
Employ refresh token rotation and revocation. When a refresh token is used to obtain a new access token, the authentication server should invalidate the old refresh token and issue a new one. This “rotating refresh token” strategy limits the window of vulnerability if a refresh token is compromised. Always encrypt sensitive data, including tokens, even when stored in secure enclaves. Implement proper error handling for token expiry and invalidation, guiding the user back to re-authentication when necessary. Consider device registration and multi-factor authentication (MFA) for enhanced security, especially for sensitive operations.
Edge case interviewers probe for
An interviewer might ask, “What if a user’s device is lost or stolen, and the refresh token is compromised?” The correct response is to implement an immediate token revocation mechanism. Users should be able to log out from all devices via a web portal, which would send a signal to the authentication server to invalidate all refresh tokens associated with that user. Another probe is, “How do you handle an expired access token during an API call?” The mobile application should automatically attempt to refresh the access token using the stored refresh token. If successful, retry the original API call. If refresh fails, prompt the user for re-authentication.
Common mistake
A common mistake is storing tokens in insecure locations, such as unencrypted SharedPreferences on Android or UserDefaults on iOS, making them vulnerable to other apps or rooted devices. Another error is failing to implement refresh token rotation or not having a mechanism for server-side refresh token invalidation, which leaves long-lived tokens susceptible to indefinite misuse if compromised. Developers also often overlook certificate pinning, making the application vulnerable to network interception and man-in-the-middle attacks.
What the interviewer is checking
The interviewer is assessing your understanding of secure mobile development practices, your knowledge of OAuth 2.0 and JWTs, and your ability to apply these concepts to real-world mobile constraints. They are looking for a security-first mindset, practical experience with mobile secure storage, and a comprehensive approach to handling token lifecycle, including refresh, revocation, and error conditions. Demonstrating awareness of common attack vectors and mitigation strategies for mobile apps is crucial.
Imagine you’re going to a special concert where your identity needs to be checked often. When you first arrive and show your ID at the main entrance (your login), you get two things: a small paper wristband and a special VIP laminate pass. The paper wristband is like your “access token” – it’s valid for getting into most areas, but it tears easily and expires quickly. The VIP laminate pass is your “refresh token” – it’s much tougher, lasts longer, and lets you go to a special kiosk to trade in your old, torn paper wristband for a brand new one without showing your ID again.
So, you use your paper wristband to get into different sections of the concert. If a bouncer sees your wristband is torn or expired, you quickly go to the VIP kiosk, show your VIP laminate pass, and they give you a fresh new paper wristband, often taking your old VIP pass and giving you a new one too, just to be extra safe. If you lose your VIP laminate pass, you’re out of luck and have to go all the way back to the main entrance and show your ID again to get back in. The mobile app securely stores these “passes” so other concert-goers can’t steal them.
Why interviewers ask this
Interviewers ask this to gauge your practical experience with mobile security, your understanding of modern authentication protocols like OAuth 2.0 and JWTs, and your ability to design resilient systems. It demonstrates your awareness of mobile-specific challenges and how to mitigate security risks.
What a strong answer signals
A strong answer signals a security-first mindset, deep knowledge of token lifecycle management (generation, storage, refresh, revocation), and an understanding of platform-specific security mechanisms. It shows you can balance security requirements with user experience in a mobile context.
Common follow-ups
- How would you integrate biometric authentication (e.g., Face ID, Touch ID) into this system?
- What are the risks of using JWTs without encryption, and how can they be mitigated for sensitive data?
- How would you handle global session revocation or “logout from all devices” functionality?
Advanced variation
Design a system that supports multiple authentication providers (e.g., social logins like Google, Apple, Facebook) while maintaining a unified authorization layer for your application’s internal services, ensuring consistent user profiles and permissions across all login methods.
Consider a mobile banking application. Instead of requiring the user to re-enter their full credentials every time they want to view their balance or make a transfer, the app uses a token-based system. An initial login grants an access token for general browsing and a refresh token for extended sessions. For highly sensitive actions like initiating a transfer, the app might prompt for a biometric scan or a transaction PIN, which locally re-authorizes a very short-lived, transaction-specific token, adding an extra layer of security without forcing a full re-login for every sensitive action.
// auth_service.js - Simplified Token Refresh Logic for Mobile (Conceptual)
class AuthService {
constructor() {
this.accessToken = null;
this.refreshToken = null;
this.tokenExpiry = null; // Unix timestamp for access token expiry
}
// In a real app, securely retrieve from iOS Keychain / Android Keystore
async getStoredTokens() {
this.accessToken = localStorage.getItem('access_token');
this.refreshToken = localStorage.getItem('refresh_token');
this.tokenExpiry = parseInt(localStorage.getItem('token_expiry'), 10);
}
// In a real app, securely save to iOS Keychain / Android Keystore
async saveTokens(accessToken, refreshToken, expiresInSeconds) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.tokenExpiry = Date.now() + (expiresInSeconds * 1000);
localStorage.setItem('access_token', accessToken);
localStorage.setItem('refresh_token', refreshToken);
localStorage.setItem('token_expiry', this.tokenExpiry.toString());
}
async isAuthenticated() {
await this.getStoredTokens();
if (!this.accessToken || !this.refreshToken) {
return false;
}
// Check if access token is expired or close to expiration (e.g., within 30s)
if (Date.now() >= this.tokenExpiry - 30000) {
return await this.refreshAccessToken();
}
return true;
}
async refreshAccessToken() {
if (!this.refreshToken) {
console.log('No refresh token available. User must re-authenticate.');
return false;
}
console.log('Attempting to refresh access token...');
try {
// Simulate an API call to your authentication server for token refresh
// In a real app, this would be a fetch/axios call
const newAccessToken = 'new_jwt_access_token_' + Date.now();
const newRefreshToken = 'new_jwt_refresh_token_' + Date.now(); // Refresh token rotation
const expiresIn = 3600; // New access token valid for 1 hour
await this.saveTokens(newAccessToken, newRefreshToken, expiresIn);
console.log('Tokens refreshed successfully.');
return true;
} catch (error) {
console.error('Failed to refresh token:', error);
this.clearTokens(); // Force re-login on refresh failure
return false;
}
}
clearTokens() {
this.accessToken = null;
this.refreshToken = null;
this.tokenExpiry = null;
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
localStorage.removeItem('token_expiry');
console.log('All tokens cleared.');
}
getAccessToken() {
return this.accessToken;
}
}
// Example usage (conceptual, without actual network calls)
const authService = new AuthService();
async function init() {
await authService.getStoredTokens();
if (await authService.isAuthenticated()) {
console.log('User is authenticated. Access token:', authService.getAccessToken());
} else {
console.log('User not authenticated. Please log in.');
// Simulate login, get initial tokens (Access token expires in 60s for demo)
await authService.saveTokens('initial_access_token_123', 'initial_refresh_token_abc', 60);
console.log('Simulated login. Access token:', authService.getAccessToken());
}
}
init();
- 1Mobile authentication requires careful handling of tokens for security and user experience.
- 2Token-based systems like OAuth 2.0 with JWTs are standard for mobile applications.
- 3Short-lived access tokens and long-lived refresh tokens enhance security by limiting exposure.
- 4Secure storage mechanisms like Keychain/Keystore are critical for protecting sensitive tokens on the device.
- 5Token rotation, revocation, and robust error handling are essential for a resilient authentication system.