Fix session persistence issue

- Created SSR-safe tokenStorage utility for localStorage access
- Updated AuthContext with window availability checks
- Enhanced API client interceptors with SSR safety
- Improved error handling to only clear tokens on auth errors (401/403)
- Added token refresh support for multiple response structures
- Added redirect loop prevention in auth flow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
andupetcu
2025-09-30 21:57:37 +03:00
parent b6ed413e0c
commit b48aaded05
3 changed files with 173 additions and 24 deletions

View File

@@ -0,0 +1,93 @@
/**
* Safe token storage utilities that work with both SSR and client-side rendering
*/
export const tokenStorage = {
/**
* Get access token from storage
*/
getAccessToken: (): string | null => {
if (typeof window === 'undefined') {
return null;
}
try {
return localStorage.getItem('accessToken');
} catch (error) {
console.error('Error reading accessToken:', error);
return null;
}
},
/**
* Get refresh token from storage
*/
getRefreshToken: (): string | null => {
if (typeof window === 'undefined') {
return null;
}
try {
return localStorage.getItem('refreshToken');
} catch (error) {
console.error('Error reading refreshToken:', error);
return null;
}
},
/**
* Set access token in storage
*/
setAccessToken: (token: string): void => {
if (typeof window === 'undefined') {
return;
}
try {
localStorage.setItem('accessToken', token);
} catch (error) {
console.error('Error setting accessToken:', error);
}
},
/**
* Set refresh token in storage
*/
setRefreshToken: (token: string): void => {
if (typeof window === 'undefined') {
return;
}
try {
localStorage.setItem('refreshToken', token);
} catch (error) {
console.error('Error setting refreshToken:', error);
}
},
/**
* Set both tokens at once
*/
setTokens: (accessToken: string, refreshToken: string): void => {
tokenStorage.setAccessToken(accessToken);
tokenStorage.setRefreshToken(refreshToken);
},
/**
* Clear all tokens from storage
*/
clearTokens: (): void => {
if (typeof window === 'undefined') {
return;
}
try {
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
} catch (error) {
console.error('Error clearing tokens:', error);
}
},
/**
* Check if user has valid tokens
*/
hasTokens: (): boolean => {
return !!(tokenStorage.getAccessToken() && tokenStorage.getRefreshToken());
},
};