Implement cookie auth on frontend

This commit is contained in:
2024-12-09 20:57:56 +01:00
parent 8a62c9e306
commit 26a208123a
2 changed files with 41 additions and 56 deletions

View File

@@ -19,16 +19,10 @@ export const AuthProvider = ({ children }) => {
useEffect(() => {
const initializeAuth = async () => {
try {
const storedToken = localStorage.getItem('accessToken');
if (storedToken) {
authApi.setAuthToken(storedToken);
const userData = await authApi.getCurrentUser();
setUser(userData);
}
} catch (error) {
console.error('Failed to initialize auth:', error);
localStorage.removeItem('accessToken');
authApi.clearAuthToken();
} finally {
setLoading(false);
setInitialized(true);
@@ -40,12 +34,7 @@ export const AuthProvider = ({ children }) => {
const login = useCallback(async (email, password) => {
try {
const { accessToken, user: userData } = await authApi.login(
email,
password
);
localStorage.setItem('accessToken', accessToken);
authApi.setAuthToken(accessToken);
const { user: userData } = await authApi.login(email, password);
setUser(userData);
notifications.show({
title: 'Success',
@@ -70,18 +59,17 @@ export const AuthProvider = ({ children }) => {
} catch (error) {
console.error('Logout failed:', error);
} finally {
localStorage.removeItem('accessToken');
authApi.clearAuthToken();
setUser(null);
}
}, []);
const refreshToken = useCallback(async () => {
try {
const { accessToken } = await authApi.refreshToken();
localStorage.setItem('accessToken', accessToken);
authApi.setAuthToken(accessToken);
return true;
const success = await authApi.refreshToken();
if (!success) {
await logout();
}
return success;
} catch (error) {
console.error('Token refresh failed:', error);
await logout();

View File

@@ -1,40 +1,32 @@
import { API_BASE_URL } from '../utils/constants';
let authToken = null;
export const setAuthToken = (token) => {
authToken = token;
};
export const clearAuthToken = () => {
authToken = null;
};
export const getAuthHeaders = () => {
const headers = {
'Content-Type': 'application/json',
};
if (authToken) {
headers['Authorization'] = `Bearer ${authToken}`;
}
return headers;
};
// Update the existing apiCall function to include auth headers
export const apiCall = async (url, options = {}) => {
try {
const headers = {
...getAuthHeaders(),
'Content-Type': 'application/json',
...options.headers,
};
if (options.method && options.method !== 'GET') {
const csrfToken = document.cookie
.split('; ')
.find((row) => row.startsWith('csrf_token='))
?.split('=')[1];
if (csrfToken) {
headers['X-CSRF-Token'] = csrfToken;
}
}
const response = await fetch(url, {
...options,
headers,
credentials: 'include',
});
if (response.status === 429) {
throw new Error('Rate limit exceeded');
}
// Handle 401 responses
if (response.status === 401) {
const isRefreshEndpoint = url.endsWith('/auth/refresh');
@@ -42,13 +34,14 @@ export const apiCall = async (url, options = {}) => {
// Attempt token refresh and retry the request
const refreshSuccess = await refreshToken();
if (refreshSuccess) {
// Retry the original request with the new token
// Retry the original request
return apiCall(url, options);
}
}
throw new Error('Authentication failed');
}
// Handle other error responses
if (!response.ok && response.status !== 204) {
const errorData = await response.json().catch(() => null);
throw new Error(
@@ -56,6 +49,7 @@ export const apiCall = async (url, options = {}) => {
);
}
// Return null for 204 responses
if (response.status === 204) {
return null;
}
@@ -73,26 +67,29 @@ export const login = async (email, password) => {
method: 'POST',
body: JSON.stringify({ email, password }),
});
return response.json();
const data = await response.json();
// No need to store tokens as they're in cookies now
return data;
};
export const logout = async () => {
const sessionId = localStorage.getItem('sessionId');
await apiCall(`${API_BASE_URL}/auth/logout`, {
method: 'POST',
headers: {
'X-Session-ID': sessionId,
},
});
return;
};
export const refreshToken = async () => {
const refreshToken = localStorage.getItem('refreshToken');
try {
const response = await apiCall(`${API_BASE_URL}/auth/refresh`, {
method: 'POST',
body: JSON.stringify({ refreshToken }),
});
return response.json();
return response.status === 200;
} catch (error) {
console.error('Token refresh failed:', error);
return false;
}
};
export const getCurrentUser = async () => {