Files
geo/api/src/Core/Session.php
pierre 2f5946a184 feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles
- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD)
  * DEV: Clés TEST Pierre (mode test)
  * REC: Clés TEST Client (mode test)
  * PROD: Clés LIVE Client (mode live)
- Ajout de la gestion des bases de données immeubles/bâtiments
  * Configuration buildings_database pour DEV/REC/PROD
  * Service BuildingService pour enrichissement des adresses
- Optimisations pages et améliorations ergonomie
- Mises à jour des dépendances Composer
- Nettoyage des fichiers obsolètes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:26:27 +01:00

179 lines
7.6 KiB
PHP
Executable File

<?php
declare(strict_types=1);
class Session {
public static function start(): void {
if (session_status() === PHP_SESSION_NONE) {
// Configuration d'un répertoire de sessions dédié et persistant
$sessionPath = __DIR__ . '/../../sessions';
if (!is_dir($sessionPath)) {
mkdir($sessionPath, 0700, true);
}
ini_set('session.save_path', $sessionPath);
// Configuration des sessions adaptée pour les applications mobiles
ini_set('session.use_strict_mode', '1');
ini_set('session.cookie_httponly', '1');
// Permettre les connexions non-HTTPS en développement
$isProduction = (getenv('APP_ENV') === 'production');
ini_set('session.cookie_secure', $isProduction ? '1' : '0');
// SameSite None pour permettre les requêtes cross-origin (applications mobiles)
ini_set('session.cookie_samesite', 'None');
// Configuration de la durée de vie des sessions : 24 heures
$sessionLifetime = 86400; // 24 heures
ini_set('session.gc_maxlifetime', (string)$sessionLifetime);
ini_set('session.cookie_lifetime', (string)$sessionLifetime);
// Configuration du garbage collector pour qu'il ne supprime pas trop tôt
// gc_probability / gc_divisor = probabilité d'exécution (1/100 = 1%)
ini_set('session.gc_probability', '1');
ini_set('session.gc_divisor', '100');
// Récupérer le session_id du Bearer token si présent
self::getSessionFromBearer();
session_start();
// Log détaillé après le démarrage de la session (DEBUG)
$logFile = __DIR__ . '/../../logs/session_' . date('Y-m-d') . '.log';
$sessionId = session_id();
$sessionExists = isset($_SESSION) && !empty($_SESSION);
$sessionData = $sessionExists ? json_encode($_SESSION) : 'empty';
$sessionFile = $sessionPath . '/sess_' . $sessionId;
$sessionFileExists = file_exists($sessionFile);
$logMessage = date('Y-m-d H:i:s') . " - Session started\n";
$logMessage .= " Session ID: $sessionId\n";
$logMessage .= " Session path: $sessionPath\n";
$logMessage .= " Session file exists: " . ($sessionFileExists ? 'YES' : 'NO') . "\n";
$logMessage .= " Session data exists: " . ($sessionExists ? 'YES' : 'NO') . "\n";
$logMessage .= " Session data: $sessionData\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
}
}
public static function login(array $userData): void {
$_SESSION['user_id'] = $userData['id'];
$_SESSION['user_email'] = $userData['email'] ?? '';
$_SESSION['entity_id'] = $userData['fk_entite'] ?? null;
$_SESSION['fk_role'] = $userData['fk_role'] ?? 1;
$_SESSION['authenticated'] = true;
$_SESSION['last_activity'] = time();
// Régénère l'ID de session pour éviter la fixation de session
session_regenerate_id(true);
}
public static function logout(): void {
session_unset();
session_destroy();
}
public static function isAuthenticated(): bool {
return isset($_SESSION['authenticated']) && $_SESSION['authenticated'] === true;
}
public static function getUserId(): ?int {
return $_SESSION['user_id'] ?? null;
}
public static function getUserEmail(): ?string {
return $_SESSION['user_email'] ?? null;
}
public static function getEntityId(): ?int {
return $_SESSION['entity_id'] ?? null;
}
public static function getRole(): ?int {
return $_SESSION['fk_role'] ?? null;
}
public static function requireAuth(): void {
if (!self::isAuthenticated()) {
// Log détaillé pour le debug
$logFile = __DIR__ . '/../../logs/auth_' . date('Y-m-d') . '.log';
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? 'No Authorization header';
$appId = isset($_SERVER['HTTP_X_APP_IDENTIFIER']) ? $_SERVER['HTTP_X_APP_IDENTIFIER'] : 'No App Identifier';
$method = $_SERVER['REQUEST_METHOD'] ?? 'Unknown Method';
$uri = $_SERVER['REQUEST_URI'] ?? 'Unknown URI';
$logMessage = "\n===== AUTHENTICATION FAILURE =====\n";
$logMessage .= "Date: " . date('Y-m-d H:i:s') . "\n";
$logMessage .= "Method: $method\n";
$logMessage .= "URI: $uri\n";
$logMessage .= "App ID: $appId\n";
$logMessage .= "Auth Header: $authHeader\n";
$logMessage .= "Session data: " . (isset($_SESSION) ? json_encode($_SESSION) : 'No session') . "\n";
$logMessage .= "================================\n";
file_put_contents($logFile, $logMessage, FILE_APPEND);
Response::json(['error' => 'Non authentifié - Veuillez vous connecter'], 401);
exit;
}
}
// Vérification optionnelle de l'activité
public static function checkActivity(): void {
$inactiveTime = 3600; // 1 heure
if (
isset($_SESSION['last_activity']) &&
(time() - $_SESSION['last_activity'] > $inactiveTime)
) {
self::logout();
Response::json(['error' => 'Session expirée'], 440);
exit;
}
$_SESSION['last_activity'] = time();
}
// Récupère le session_id du Bearer token et le définit comme session_id courant
private static function getSessionFromBearer(): void {
// Vérifier si le header Authorization est présent
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
// Mettre toutes les erreurs dans un fichier de log dédié
$logFile = __DIR__ . '/../../logs/session_' . date('Y-m-d') . '.log';
file_put_contents($logFile, date('Y-m-d H:i:s') . " - Auth Header: " . $authHeader . "\n", FILE_APPEND);
// Nettoyage du header d'autorisation
$authHeader = trim($authHeader);
// Support de plusieurs formats possibles
if (strpos($authHeader, 'Bearer ') === 0) {
// Format standard "Bearer token"
$sessionId = substr($authHeader, 7);
} elseif (strpos(strtolower($authHeader), 'bearer ') === 0) {
// Cas insensible à la casse
$sessionId = substr($authHeader, 7);
} elseif (preg_match('/^bearer\s+(.*)$/i', $authHeader, $matches)) {
// Utilisation de l'expression régulière
$sessionId = $matches[1];
} else {
file_put_contents($logFile, date('Y-m-d H:i:s') . " - No Bearer token found in Authorization header\n", FILE_APPEND);
return;
}
// Nettoyage du token
$sessionId = trim($sessionId);
file_put_contents($logFile, date('Y-m-d H:i:s') . " - Session ID extracted: " . $sessionId . "\n", FILE_APPEND);
// Vérifier que le session_id a un format valide (alphanumerique avec quelques caractères spéciaux)
// Attention: les sessions en PHP peuvent contenir des caractères non-alphanumériques
// Assouplir les règles de validation si nécessaire
if (!empty($sessionId) && strlen($sessionId) <= 128) {
// Définir l'ID de session avant de démarrer la session
session_id($sessionId);
file_put_contents($logFile, date('Y-m-d H:i:s') . " - Session ID set: " . $sessionId . "\n", FILE_APPEND);
} else {
file_put_contents($logFile, date('Y-m-d H:i:s') . " - Invalid session ID format in Bearer token\n", FILE_APPEND);
}
}
}