Skip to content

feat: implement JWT token auto-refresh mechanism#37

Merged
fishonamos merged 1 commit into
gear5labs:buildfrom
gelluisaac:feat
Mar 27, 2026
Merged

feat: implement JWT token auto-refresh mechanism#37
fishonamos merged 1 commit into
gear5labs:buildfrom
gelluisaac:feat

Conversation

@gelluisaac

Copy link
Copy Markdown
Collaborator

closes #16

Summary

This PR implements a comprehensive JWT token auto-refresh system that automatically handles token expiration and renewal, ensuring seamless user authentication without requiring manual intervention.

Problem Solved

Previously, when JWT tokens expired, users would experience authentication failures and need to manually re-login. This implementation automatically detects expired tokens and refreshes them in the background, providing a smooth user experience.

Changes Made

🏗️ Core Services

  • TokenRefreshService (src/services/tokenRefreshService.ts)
    • Singleton pattern for centralized refresh management
    • Request queue to prevent multiple simultaneous refresh attempts
    • Automatic retry mechanism for failed refresh requests
    • Thread-safe token refresh operations

🔧 API Service Enhancements

  • Enhanced ApiService (src/services/api.ts)
    • Axios response interceptor that automatically catches 401 Unauthorized errors
    • Seamless token refresh using direct axios call to avoid circular dependencies
    • Automatic retry of original requests after successful token refresh
    • Fallback to login redirect when refresh fails
    • Added refreshToken() method for manual refresh capabilities

📦 Redux Store Integration

  • AuthSlice Updates (src/store/slices/authSlice.ts)
    • New refreshToken async thunk for centralized state management
    • Proper loading states and error handling for refresh operations
    • Automatic localStorage synchronization on token updates
    • Cleanup of authentication data on refresh failure

🪝 Custom Hooks

  • useTokenRefresh Hook (src/hooks/useTokenRefresh.ts)
    • Easy access to token refresh functionality throughout the application
    • JWT token expiration detection using payload parsing
    • Manual and automatic refresh methods
    • Real-time status tracking (loading, error, expired states)

🎨 UI Components

  • TokenRefreshExample (src/components/examples/TokenRefreshExample.tsx)
    • Comprehensive demonstration of token refresh functionality
    • Real-time monitoring of token status and refresh operations
    • Manual and automatic refresh controls for testing
    • Visual feedback for loading states and errors

Features Implemented

Automatic Token Refresh - Background token renewal on 401 errors
Request Queue Management - Prevents duplicate refresh requests
Token Expiration Detection - JWT payload parsing for proactive refresh
Redux State Management - Centralized authentication state
Error Handling - Comprehensive error handling with user feedback
TypeScript Support - Full type safety throughout the system
LocalStorage Sync - Persistent token storage and cleanup
Retry Mechanism - Automatic retry of failed requests after refresh
Security Best Practices - No circular dependencies, secure token handling

How It Works

Automatic Flow

  1. API Request: Any authenticated API call includes JWT token in Authorization header
  2. 401 Detection: Axios interceptor catches 401 Unauthorized responses
  3. Token Refresh: Automatic call to /auth/refresh endpoint
  4. Request Retry: Original request is retried with new token
  5. State Update: Redux store and localStorage updated with new token
  6. Fallback: Redirect to login if refresh fails

Manual Flow

  1. Hook Usage: Components can use useTokenRefresh() hook
  2. Expiration Check: isTokenExpired() checks JWT payload
  3. Manual Refresh: refreshToken() forces token renewal
  4. Conditional Refresh: refreshTokenIfNeeded() only refreshes if expired

Usage Examples

Automatic Usage (Recommended)

// No code needed - works automatically!
const data = await apiService.getProfile(); // Auto-refreshes on 401

Manual Usage with Hook

import { useTokenRefresh } from '@/hooks/useTokenRefresh';

function MyComponent() {
  const { refreshToken, refreshTokenIfNeeded, isRefreshing } = useTokenRefresh();
  
  const handleRefresh = async () => {
    await refreshToken(); // Force refresh
  };
  
  const handleConditionalRefresh = async () => {
    await refreshTokenIfNeeded(); // Only if expired
  };
}

Redux Dispatch

import { refreshToken } from '@/store/slices/authSlice';

// Manual refresh via Redux
dispatch(refreshToken());

Security Considerations

🔒 Circular Dependency Prevention: Refresh endpoint uses direct axios call
🔒 Request Deduplication: Queue prevents multiple simultaneous refreshes
🔒 Token Validation: JWT expiration checking before API calls
🔒 Secure Storage: Proper localStorage management with cleanup
🔒 Error Boundaries: Comprehensive error handling prevents data leaks

Testing

The implementation includes:

  • TokenRefreshExample Component: Interactive testing interface
  • Manual Refresh Controls: Test manual token refresh
  • Auto-Refresh Testing: Verify automatic refresh behavior
  • Error Scenarios: Test refresh failure handling
  • Status Monitoring: Real-time token status display

Performance Impact

Minimal Overhead: Only activates on 401 errors
Request Deduplication: Prevents unnecessary API calls
Efficient Queue Management: Non-blocking refresh operations
Optimized State Updates: Minimal Redux re-renders

Breaking Changes

None. This is a non-breaking addition that enhances existing authentication functionality.

Migration Guide

No migration required. Existing code will automatically benefit from the new token refresh mechanism.

Future Enhancements

  • Token refresh before expiration (proactive refresh)
  • Refresh token rotation for enhanced security
  • Offline token refresh capabilities
  • Token refresh analytics and monitoring
  • Custom refresh strategies per endpoint

Testing Checklist

  • Automatic token refresh on 401 errors
  • Manual token refresh functionality
  • Token expiration detection
  • Redux state management
  • Error handling and fallbacks
  • localStorage synchronization
  • TypeScript type safety
  • Request queue management
  • Component integration

Impact

This implementation significantly improves user experience by:

  • Eliminating authentication failures due to token expiration
  • Reducing manual login requirements
  • Providing seamless background token management
  • Enhancing application reliability and stability
  • Improving developer experience with easy-to-use hooks

The JWT token auto-refresh mechanism is now fully integrated and ready for production use.

- Add TokenRefreshService with singleton pattern for managing refresh requests
- Implement request queue to prevent multiple simultaneous refresh attempts
- Add Axios response interceptor for automatic 401 error handling
- Create refreshToken method in ApiService using direct axios call
- Add refreshToken async thunk to Redux auth slice with proper state management
- Create useTokenRefresh custom hook for easy access to refresh functionality
- Add TokenRefreshExample component demonstrating the auto-refresh features
- Implement token expiration detection using JWT payload parsing
- Add comprehensive error handling and fallback to login on refresh failure
- Ensure localStorage synchronization for token persistence
- Support TypeScript with proper typing throughout the implementation

This provides seamless JWT token management with automatic refresh on API failures.
@vercel

vercel Bot commented Mar 27, 2026

Copy link
Copy Markdown

@gelluisaac is attempting to deploy a commit to the Fishon Amos' projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Mar 27, 2026

Copy link
Copy Markdown

@gelluisaac Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@fishonamos fishonamos merged commit ff9f950 into gear5labs:build Mar 27, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Frontend] Implement JWT Token Auto-Refresh

2 participants