Authentication Architecture
Comprehensive guide to authentication implementation, token management, and session handling.
Authentication Architecture
Overview
This document outlines our authentication architecture, covering token management, session handling, and security best practices. It provides implementation details for authentication flows, automatic token refresh, and secure storage patterns.
Purpose & Scope
This guide covers:
- Authentication flow implementation
- Token storage and management
- Session lifecycle handling
- Security considerations
- Integration with API client
Prerequisites
To get the most out of this document, we recommend you first understand these key areas and review the related guides:
- API Client Architecture: Familiarity with the concepts and patterns outlined in the API Client Architecture is essential, as this document builds upon the
BaseApiClient,PublicApiClient, andAuthenticatedApiClientstructures defined therein.
Architecture Overview
Authentication Domain Structure
Core Components
1. Token Service
Manages token storage and retrieval without importing state:
2. Secure Storage Implementation
Platform-specific secure storage:
3. API Client Architecture
Note: This section builds upon the core API client structure defined in the API Client Architecture. We do not redefine the base patterns here, but rather show how they are extended to support authentication specifically. Please refer to the API Client Architecture Guide for the complete definition of the foundational
BaseApiClientclass and overall API client patterns.
We use a type-safe, inheritance-based approach for handling public vs authenticated endpoints. The core classes are BaseApiClient, PublicApiClient, and AuthenticatedApiClient. Below, we illustrate how PublicApiClient and AuthenticatedApiClient extend the foundational BaseApiClient.
The PublicApiClient extends BaseApiClient and is used for API endpoints that do not require authentication. It typically does not add further logic beyond what BaseApiClient provides for public access.
To make these API client classes usable throughout the application, singleton instances are typically created and exported. This is often managed in a central API client configuration module. The following example illustrates this pattern:
This approach is the established standard for all API implementations in our project, as it provides several key benefits:
- Clear separation between public and authenticated endpoints
- Type safety without runtime flags
- Scalability for multiple API services
- Consistent error handling
- Automatic token refresh management
For detailed implementation patterns and multiple API support, see the API Client Architecture.
4. Auth API Service
Authentication endpoints following the mandatory public/protected pattern:
Adhering to this structure for all domain APIs is strongly recommended to ensure consistency and leverage the following benefits:
- Explicit separation of public vs authenticated endpoints
- Type-safe API calls
- Consistent patterns across all domains
- Better IntelliSense support
5. Auth Hooks
React Query hooks following the enforced API pattern:
6. Auth State Store
Client-side auth state management:
7. Auth Events
Event-driven auth state changes:
Authentication Flows
1. Login Flow
2. Token Refresh Flow
3. Logout Flow
Implementation Examples
1. Login Screen
2. App-Level Auth Handling
3. Protected API Calls
Security Considerations
1. Token Storage
- Use platform-specific secure storage (Keychain/Keystore)
- Never store tokens in plain text
- Clear tokens on logout
- Implement token expiration checks
2. API Security
- Always use HTTPS
- Implement certificate pinning for production
- Validate SSL certificates
- Use short-lived access tokens (15-30 minutes)
- Use longer-lived refresh tokens (7-30 days)
3. Session Management
- Implement idle timeout
- Clear sensitive data on app background
- Re-authenticate for sensitive operations
- Log security events
4. Error Handling
Testing Authentication
1. Unit Tests
2. Integration Tests
Troubleshooting
Common Issues
-
Token Refresh Loop
- Check refresh endpoint URL
- Verify refresh token validity
- Check for clock skew
-
Session Not Persisting
- Verify secure storage implementation
- Check persistence configuration
- Validate token expiration
-
401 Errors After Login
- Check Authorization header format
- Verify token is being sent
- Check API endpoint configuration
Migration Guide
For existing apps migrating to this architecture:
-
Phase 1: Token Service
- Implement token service
- Migrate from existing storage
-
Phase 2: API Client
- Add interceptors
- Implement refresh logic
-
Phase 3: Auth Domain
- Create auth domain structure
- Migrate auth logic
-
Phase 4: Event System
- Implement auth events
- Update navigation handling
Design Principles
Core Architectural Principles
-
Separation of Concerns
- Token management is isolated from business logic
- API client handles authentication transparently to consumers
- Events decouple authentication status from UI responses
-
Defense in Depth
- Token storage uses platform-specific secure storage
- Refresh tokens are handled with appropriate security measures
- Automatic session termination on security breaches
-
Developer Ergonomics
- Type-safe API client implementation
- Consistent error handling patterns
- Clear separation between public/authenticated endpoints
Trade-offs and Design Decisions
| Decision | Benefits | Drawbacks | Rationale |
|---|---|---|---|
| Separate Token Service | Modular, testable, no circular dependencies | More code to maintain | Enables independent testing and prevents circular imports |
| Automatic Token Refresh | Seamless UX, fewer session timeouts | More complex API client | User experience benefits outweigh implementation complexity |
| Event-based Auth Status | Loose coupling between components | Asynchronous flow can be harder to debug | Allows for flexible responses to auth events across the app |
| Platform-specific Secure Storage | Uses best-available security per platform | Requires platform-specific code | Maximum security is critical for auth tokens |
Constraints and Considerations
- Authentication implementation must handle various network conditions
- Token refresh must work reliably to prevent disruption
- API error handling must account for various auth-related errors
- Deep linking and external app authentication flows must be supported
Implementation Considerations
Performance Implications
- Token Validation: Performed locally when possible to reduce network requests
- Caching: Auth status cached to minimize secure storage access which can be slow
- API Design: Authentication header injection optimized to minimize overhead
Security Considerations
- Token Storage: Never store in AsyncStorage/LocalStorage unencrypted
- XSS Protection: Tokens never accessible to WebViews or JavaScript bridges
- Refresh Logic: Implements exponential backoff for failed refresh attempts
- Biometric Integration: Optional biometric verification for high-security operations
Scalability Aspects
- Architecture supports multiple authentication methods (email/password, social, SSO)
- Design allows for additional auth providers without changing core implementation
- Supports multiple concurrent user profiles when needed
Related Documents
- API Client with Request Queueing - Detailed implementation of request queueing during token refresh
- API Client Architecture - Mandatory patterns for API client implementation
- Core Architecture - Overview of the application's hybrid architecture
- Communication Patterns - Inter-module communication
- security - Application security best practices
- api-integration - Implementation guide for API integration
- state-management