Initial commit - SOGOMS v1.0.0
- sogoctl: supervisor avec health checks et restart auto - sogoway: gateway HTTP, auth JWT, routing par hostname - sogoms-db: microservice MariaDB avec pool par application - Protocol IPC Unix socket JSON length-prefixed - Config YAML multi-application (prokov) - Deploy script pour container Alpine gw3 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
162
clients/prokov/api/core/Session.php
Normal file
162
clients/prokov/api/core/Session.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/**
|
||||
* Gestion des sessions en base de données
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
class Session
|
||||
{
|
||||
private static ?array $currentSession = null;
|
||||
private static ?array $currentUser = null;
|
||||
|
||||
/**
|
||||
* Récupérer l'IP réelle du client (derrière proxy)
|
||||
*/
|
||||
public static function getClientIp(): ?string
|
||||
{
|
||||
// Headers transmis par le proxy nginx
|
||||
$headers = [
|
||||
'HTTP_X_REAL_IP',
|
||||
'HTTP_X_FORWARDED_FOR',
|
||||
'HTTP_CLIENT_IP',
|
||||
'REMOTE_ADDR',
|
||||
];
|
||||
|
||||
foreach ($headers as $header) {
|
||||
if (!empty($_SERVER[$header])) {
|
||||
// X-Forwarded-For peut contenir plusieurs IPs (client, proxy1, proxy2...)
|
||||
$ips = explode(',', $_SERVER[$header]);
|
||||
$ip = trim($ips[0]);
|
||||
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP)) {
|
||||
return $ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Créer une nouvelle session pour un utilisateur
|
||||
*/
|
||||
public static function create(int $userId, ?string $ipAddress = null, ?string $userAgent = null): string
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
$sessionId = bin2hex(random_bytes(64)); // 128 caractères
|
||||
$expiresAt = date('Y-m-d H:i:s', time() + SESSION_LIFETIME);
|
||||
|
||||
$stmt = $db->prepare('
|
||||
INSERT INTO sessions (id, user_id, ip_address, user_agent, expires_at)
|
||||
VALUES (:id, :user_id, :ip_address, :user_agent, :expires_at)
|
||||
');
|
||||
|
||||
$stmt->execute([
|
||||
'id' => $sessionId,
|
||||
'user_id' => $userId,
|
||||
'ip_address' => $ipAddress ?? self::getClientIp(),
|
||||
'user_agent' => $userAgent ?? $_SERVER['HTTP_USER_AGENT'] ?? null,
|
||||
'expires_at' => $expiresAt,
|
||||
]);
|
||||
|
||||
return $sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Valider une session et retourner l'utilisateur
|
||||
*/
|
||||
public static function validate(string $sessionId): ?array
|
||||
{
|
||||
if (self::$currentSession !== null && self::$currentSession['id'] === $sessionId) {
|
||||
return self::$currentUser;
|
||||
}
|
||||
|
||||
$db = Database::getInstance();
|
||||
|
||||
$stmt = $db->prepare('
|
||||
SELECT s.*, u.id as user_id, u.email, u.name
|
||||
FROM sessions s
|
||||
JOIN users u ON s.user_id = u.id
|
||||
WHERE s.id = :id AND s.expires_at > NOW()
|
||||
');
|
||||
|
||||
$stmt->execute(['id' => $sessionId]);
|
||||
$result = $stmt->fetch();
|
||||
|
||||
if (!$result) {
|
||||
return null;
|
||||
}
|
||||
|
||||
self::$currentSession = [
|
||||
'id' => $result['id'],
|
||||
'user_id' => $result['user_id'],
|
||||
'expires_at' => $result['expires_at'],
|
||||
];
|
||||
|
||||
self::$currentUser = [
|
||||
'id' => $result['user_id'],
|
||||
'email' => $result['email'],
|
||||
'name' => $result['name'],
|
||||
];
|
||||
|
||||
return self::$currentUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détruire une session
|
||||
*/
|
||||
public static function destroy(string $sessionId): bool
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM sessions WHERE id = :id');
|
||||
$stmt->execute(['id' => $sessionId]);
|
||||
|
||||
self::$currentSession = null;
|
||||
self::$currentUser = null;
|
||||
|
||||
return $stmt->rowCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nettoyer les sessions expirées
|
||||
*/
|
||||
public static function cleanup(): int
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM sessions WHERE expires_at < NOW()');
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt->rowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prolonger une session
|
||||
*/
|
||||
public static function extend(string $sessionId): bool
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
$expiresAt = date('Y-m-d H:i:s', time() + SESSION_LIFETIME);
|
||||
|
||||
$stmt = $db->prepare('
|
||||
UPDATE sessions SET expires_at = :expires_at WHERE id = :id
|
||||
');
|
||||
|
||||
$stmt->execute([
|
||||
'id' => $sessionId,
|
||||
'expires_at' => $expiresAt,
|
||||
]);
|
||||
|
||||
return $stmt->rowCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtenir l'utilisateur courant (depuis le cache)
|
||||
*/
|
||||
public static function getCurrentUser(): ?array
|
||||
{
|
||||
return self::$currentUser;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user