Authentification fonctionnelle via security.lions.dev

This commit is contained in:
DahoudG
2025-11-01 14:16:20 +00:00
parent a5adb84a62
commit 1d68878601
20 changed files with 387 additions and 1067 deletions

View File

@@ -1,6 +1,6 @@
import axios from 'axios';
import { API_CONFIG } from '../config/api';
import { keycloak, KEYCLOAK_TIMEOUTS } from '../config/keycloak';
import keycloak from '../lib/keycloak';
class ApiService {
private api = axios.create({
@@ -16,8 +16,8 @@ class ApiService {
// Vérifier si Keycloak est initialisé et l'utilisateur authentifié
if (keycloak && keycloak.authenticated) {
try {
// Rafraîchir le token si nécessaire
await keycloak.updateToken(KEYCLOAK_TIMEOUTS.TOKEN_REFRESH_BEFORE_EXPIRY);
// Rafraîchir le token si nécessaire (70 secondes avant expiration)
await keycloak.updateToken(70);
// Ajouter le token Bearer à l'en-tête Authorization
if (keycloak.token) {
@@ -29,22 +29,6 @@ class ApiService {
keycloak.login();
throw error;
}
} else {
// Fallback vers l'ancien système pour la rétrocompatibilité
let token = null;
try {
const authTokenItem = sessionStorage.getItem('auth_token') || localStorage.getItem('auth_token');
if (authTokenItem) {
const parsed = JSON.parse(authTokenItem);
token = parsed.value;
}
} catch (e) {
token = localStorage.getItem('token');
}
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
}
return config;
},
@@ -73,12 +57,10 @@ class ApiService {
const hasAuthCode = currentUrl.includes('code=') && currentUrl.includes('/dashboard');
if (!hasAuthCode) {
// Fallback vers l'ancien système
localStorage.removeItem('token');
localStorage.removeItem('user');
localStorage.removeItem('auth_token');
sessionStorage.removeItem('auth_token');
window.location.href = '/api/auth/login';
console.log('❌ Non authentifié, redirection vers Keycloak...');
if (keycloak) {
keycloak.login();
}
} else {
console.log('🔄 ApiService: Erreur 401 ignorée car authentification en cours...');
}

View File

@@ -4,7 +4,7 @@
import axios, { AxiosInstance, AxiosResponse } from 'axios';
import { API_CONFIG } from '../config/api';
import { keycloak, KEYCLOAK_TIMEOUTS } from '../config/keycloak';
import keycloak from '../lib/keycloak';
import { CacheService, CacheKeys } from './cacheService';
import {
Client,
@@ -42,18 +42,30 @@ class ApiService {
// Interceptor pour les requêtes
this.api.interceptors.request.use(
async (config) => {
// Les tokens sont dans des cookies HttpOnly, automatiquement envoyés par le navigateur
// Pas besoin de les ajouter manuellement dans les headers
// Le header Authorization sera ajouté par le serveur en lisant les cookies
console.log('🔐 API Request:', config.url);
// Vérifier si Keycloak est initialisé et l'utilisateur authentifié
if (keycloak && keycloak.authenticated && keycloak.token) {
try {
// Rafraîchir le token si nécessaire (70 secondes avant expiration)
await keycloak.updateToken(70);
// Ajouter le token Bearer à l'en-tête Authorization
config.headers['Authorization'] = `Bearer ${keycloak.token}`;
console.log('✅ Token ajouté à la requête');
} catch (error) {
console.error('❌ Erreur lors de la mise à jour du token Keycloak:', error);
// En cas d'erreur, rediriger vers la page de connexion
keycloak.login();
throw error;
}
} else {
console.warn('⚠️ Keycloak non authentifié, requête sans token');
}
// Ajouter des en-têtes par défaut
config.headers['X-Requested-With'] = 'XMLHttpRequest';
// Assurer que les cookies sont envoyés avec les requêtes CORS
config.withCredentials = true;
return config;
},
(error) => {
@@ -103,16 +115,29 @@ class ApiService {
const hasAuthCode = currentUrl.includes('code=') && currentUrl.includes('/dashboard');
if (!hasAuthCode) {
console.log('🔄 Token expiré ou absent, redirection vers la connexion...');
// Sauvegarder la page actuelle pour y revenir après reconnexion
const currentPath = window.location.pathname + window.location.search;
sessionStorage.setItem('returnUrl', currentPath);
console.log('🔄 Token expiré ou absent, redirection vers Keycloak...');
// Les cookies HttpOnly seront automatiquement nettoyés par l'expiration
// ou lors de la reconnexion. Pas besoin de manipulation côté client.
// Rediriger vers la page de connexion
window.location.href = '/api/auth/login';
// Essayer de rafraîchir le token Keycloak
if (keycloak && keycloak.authenticated) {
try {
await keycloak.updateToken(-1); // Force refresh
// Retry the original request
return this.api.request(error.config);
} catch (refreshError) {
console.error('❌ Impossible de rafraîchir le token, reconnexion requise');
// Sauvegarder la page actuelle pour y revenir après reconnexion
const currentPath = window.location.pathname + window.location.search;
sessionStorage.setItem('returnUrl', currentPath);
// Rediriger vers Keycloak pour authentification
keycloak.login();
}
} else {
// Pas authentifié, rediriger vers Keycloak
console.log('❌ Non authentifié, redirection vers Keycloak...');
if (keycloak) {
keycloak.login();
}
}
} else {
console.log('🔄 API Service: Erreur 401 ignorée car authentification en cours...');
}