diff --git a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc index 7c952482daa59997e044c9f5af09e212b1a6f4eb..78bd7a0ef7bd7019670610a6016177d89c9a0e2d 100644 Binary files a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc and b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc differ diff --git a/MisplaceAI/MisplaceAI/settings.py b/MisplaceAI/MisplaceAI/settings.py index f16360060b57da255322e9e442a959f7d5b5b2c0..c913ecb9f0f74e6111c957f6beb46fd305d3a503 100644 --- a/MisplaceAI/MisplaceAI/settings.py +++ b/MisplaceAI/MisplaceAI/settings.py @@ -80,8 +80,25 @@ CSRF_TRUSTED_ORIGINS = [ # Note: CORS_ORIGIN_ALLOW_ALL is set to False for security reasons CORS_ORIGIN_ALLOW_ALL = False +CORS_ALLOW_CREDENTIALS = True +CSRF_COOKIE_HTTPONLY = True ROOT_URLCONF = 'MisplaceAI.urls' +SESSION_COOKIE_AGE = 1209600 # 2 weeks in seconds + +# Do not expire the session when the browser closes +SESSION_EXPIRE_AT_BROWSER_CLOSE = False + +# Optionally, secure the session cookie (recommended for production) +SESSION_COOKIE_SECURE = False # Set to True if using HTTPS + +# Save the session cookie on every request (optional, based on your needs) +SESSION_SAVE_EVERY_REQUEST = True + +# Configuration of the session engine +SESSION_ENGINE = 'django.contrib.sessions.backends.db' + + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index e81f19b769703c05e8a88e60ff6ebf30c274937d..26c4cd0ebb1a1f3354b2718f6a8cd3de367e72a4 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -1,6 +1,7 @@ // src/services/api.js + import axios from 'axios'; -import { refreshToken } from './auth'; +import { refreshToken, logout } from './auth'; export const getCsrfToken = () => { const cookies = document.cookie.split(';'); @@ -14,10 +15,11 @@ export const getCsrfToken = () => { }; const api = axios.create({ - baseURL: 'http://localhost:8080', // Ensure this URL is correct + baseURL: 'http://localhost:8080', headers: { 'Content-Type': 'application/json', }, + withCredentials: true, // Ensure credentials are sent with requests }); api.interceptors.request.use( @@ -34,16 +36,14 @@ api.interceptors.request.use( localStorage.setItem('token', newTokens.access); localStorage.setItem('tokenExpiry', newTokens.accessExpiry); } else { - localStorage.removeItem('token'); - localStorage.removeItem('refresh'); - localStorage.removeItem('tokenExpiry'); + console.log('Token refresh failed. Logging out...'); + logout(); window.location.href = '/login'; return Promise.reject('Session expired. Please log in again.'); } } catch (err) { - localStorage.removeItem('token'); - localStorage.removeItem('refresh'); - localStorage.removeItem('tokenExpiry'); + console.log('Error during token refresh:', err); + logout(); window.location.href = '/login'; return Promise.reject('Session expired. Please log in again.'); } @@ -56,17 +56,20 @@ api.interceptors.request.use( } return config; }, - (error) => Promise.reject(error) + (error) => { + console.log('Request error:', error); + return Promise.reject(error); + } ); api.interceptors.response.use( (response) => response, (error) => { - console.log('API error:', error); // Debugging + console.log('API error:', error); if (error.response && error.response.status === 500) { window.location.href = '/error-500'; } else if (error.request && !error.response) { - console.log('Network or server error'); // Debugging + console.log('Network or server error'); window.location.href = '/error-500'; } return Promise.reject(error); diff --git a/frontend/src/services/auth.js b/frontend/src/services/auth.js index 42da5181c94f5e8c75d253f01d2690af406e4f57..f0d90d0c339407b105eed9010d52ef43f036f25d 100644 --- a/frontend/src/services/auth.js +++ b/frontend/src/services/auth.js @@ -2,27 +2,37 @@ import api from './api'; export const login = async (credentials) => { - const response = await api.post('/api/auth/login/', credentials); - if (response.data.access) { - localStorage.setItem('token', response.data.access); - localStorage.setItem('refresh', response.data.refresh); - const tokenPayload = JSON.parse(atob(response.data.access.split('.')[1])); - localStorage.setItem('tokenExpiry', tokenPayload.exp); - localStorage.setItem('isAuthenticated', true); + try { + const response = await api.post('/api/auth/login/', credentials); + if (response.data.access) { + localStorage.setItem('token', response.data.access); + localStorage.setItem('refresh', response.data.refresh); + const tokenPayload = JSON.parse(atob(response.data.access.split('.')[1])); + localStorage.setItem('tokenExpiry', tokenPayload.exp); + localStorage.setItem('isAuthenticated', true); + } + return response.data; + } catch (error) { + console.log('Login error:', error); + throw error; } - return response.data; }; export const register = async (userData) => { - const response = await api.post('/api/auth/register/', userData); - if (response.data.access) { - localStorage.setItem('token', response.data.access); - localStorage.setItem('refresh', response.data.refresh); - const tokenPayload = JSON.parse(atob(response.data.access.split('.')[1])); - localStorage.setItem('tokenExpiry', tokenPayload.exp); - localStorage.setItem('isAuthenticated', true); + try { + const response = await api.post('/api/auth/register/', userData); + if (response.data.access) { + localStorage.setItem('token', response.data.access); + localStorage.setItem('refresh', response.data.refresh); + const tokenPayload = JSON.parse(atob(response.data.access.split('.')[1])); + localStorage.setItem('tokenExpiry', tokenPayload.exp); + localStorage.setItem('isAuthenticated', true); + } + return response.data; + } catch (error) { + console.log('Registration error:', error); + throw error; } - return response.data; }; export const logout = () => { @@ -30,6 +40,9 @@ export const logout = () => { localStorage.removeItem('refresh'); localStorage.removeItem('tokenExpiry'); localStorage.removeItem('isAuthenticated'); + localStorage.removeItem('adminToken'); + localStorage.removeItem('isAdmin'); + localStorage.removeItem('username'); }; export const refreshToken = async () => { @@ -42,26 +55,36 @@ export const refreshToken = async () => { localStorage.setItem('tokenExpiry', tokenPayload.exp); return response.data; } catch (error) { + console.log('Token refresh error:', error); logout(); + return null; } } return null; }; export const getCurrentUser = async () => { - const response = await api.get('/api/auth/user/'); - return response.data; + try { + const response = await api.get('/api/auth/user/'); + return response.data; + } catch (error) { + console.log('Get current user error:', error); + throw error; + } }; - export const adminLogin = async (credentials) => { - const response = await api.post('/api/auth/admin/login/', credentials); - if (response.data.access) { - localStorage.setItem('adminToken', response.data.access); - localStorage.setItem('isAdmin', true); - localStorage.setItem('username', credentials.username); - localStorage.setItem('isAuthenticated', true); + try { + const response = await api.post('/api/auth/admin/login/', credentials); + if (response.data.access) { + localStorage.setItem('adminToken', response.data.access); + localStorage.setItem('isAdmin', true); + localStorage.setItem('username', credentials.username); + localStorage.setItem('isAuthenticated', true); + } + return response.data; + } catch (error) { + console.log('Admin login error:', error); + throw error; } - return response.data; -} - +};