JAVASCRIPT
Secure OAuth Token Refresh Flow in JavaScript
Learn to implement a secure OAuth token refresh mechanism in JavaScript to maintain API access without re-authenticating users, handling token expiration gracefully.
async function refreshTokenAndRetry(originalRequest, accessToken, refreshToken) {
try {
const refreshResponse = await fetch('/api/token/refresh', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refreshToken })
});
if (!refreshResponse.ok) {
throw new Error('Failed to refresh token');
}
const data = await refreshResponse.json();
const newAccessToken = data.accessToken;
// Store new access token (e.g., in localStorage, secure cookie, or state)
localStorage.setItem('accessToken', newAccessToken);
// Retry the original request with the new access token
originalRequest.headers.set('Authorization', `Bearer ${newAccessToken}`);
return fetch(originalRequest);
} catch (error) {
console.error('Token refresh failed:', error);
// Redirect to login or handle session expiry
window.location.href = '/login';
throw error;
}
}
async function authenticatedFetch(url, options = {}) {
let accessToken = localStorage.getItem('accessToken');
const refreshToken = localStorage.getItem('refreshToken'); // Assuming refresh token is also stored
const headers = new Headers(options.headers || {});
headers.set('Authorization', `Bearer ${accessToken}`);
options.headers = headers;
let response = await fetch(url, options);
if (response.status === 401 && refreshToken) {
console.warn('Access token expired. Attempting to refresh...');
const originalRequest = new Request(url, options);
response = await refreshTokenAndRetry(originalRequest, accessToken, refreshToken);
}
if (!response.ok) {
// Specific error handling for failed original/retried request
console.error('API Request failed:', response.status, response.statusText);
}
return response;
}
// Example usage:
// authenticatedFetch('https://api.example.com/data')
// .then(res => res.json())
// .then(data => console.log(data))
// .catch(err => console.error(err));
How it works: This snippet provides a robust mechanism to handle expired OAuth access tokens by automatically refreshing them. When an authenticated API call returns a 401 Unauthorized status, it attempts to use a stored refresh token to obtain a new access token from a refresh endpoint. If successful, it retries the original API request with the new token. This ensures a seamless user experience by maintaining their session without requiring re-login, improving the reliability of long-lived API integrations.