Files
sistema_para_juego/shared/auth/jwt.php

201 lines
5.6 KiB
PHP
Executable File

<?php
/**
* Utilidades JWT para autenticación
* Basado en Firebase PHP-JWT
*/
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../database/connection.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class JWTAuth {
private static $secret;
private static $algorithm = 'HS256';
private static $expiration = 3600; // 1 hora por defecto
private static $userData = null; // Para almacenar los datos del usuario autenticado
private static function init() {
if (self::$secret === null) {
self::$secret = $_ENV['JWT_SECRET'] ?? getenv('JWT_SECRET');
$algo = $_ENV['JWT_ALGORITHM'] ?? getenv('JWT_ALGORITHM');
$exp = $_ENV['JWT_EXPIRATION'] ?? getenv('JWT_EXPIRATION');
if ($algo) self::$algorithm = $algo;
if ($exp) self::$expiration = (int)$exp;
}
}
/**
* Generar un token JWT
*/
public static function generateToken($userId, $username, $rol, $idioma = 'es', $permisos = []) {
self::init();
$issuedAt = time();
$expire = $issuedAt + self::$expiration;
$payload = [
'iat' => $issuedAt,
'exp' => $expire,
'iss' => $_ENV['APP_URL'] ?? getenv('APP_URL'),
'data' => [
'userId' => $userId,
'username' => $username,
'rol' => $rol,
'idioma' => $idioma,
'permissions' => $permisos // Cambiado a 'permissions' para consistencia
]
];
return JWT::encode($payload, self::$secret, self::$algorithm);
}
/**
* Validar y decodificar un token JWT
*/
public static function validateToken($token) {
self::init();
try {
$decoded = JWT::decode($token, new Key(self::$secret, self::$algorithm));
return [
'valid' => true,
'data' => $decoded->data
];
} catch (Exception $e) {
return [
'valid' => false,
'error' => $e->getMessage()
];
}
}
/**
* Refrescar un token JWT
*/
public static function refreshToken($token) {
$result = self::validateToken($token);
if (!$result['valid']) {
return null;
}
$data = $result['data'];
return self::generateToken(
$data->userId,
$data->username,
$data->rol,
$data->idioma,
(array)$data->permissions // Cambiado a 'permissions'
);
}
/**
* Extraer el token del header Authorization
*/
public static function getTokenFromHeader() {
// Compatibilidad con todos los entornos PHP
if (function_exists('getallheaders')) {
$headers = getallheaders();
} else {
$headers = [];
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
}
if (isset($headers['Authorization'])) {
$matches = [];
if (preg_match('/Bearer\s+(.*)$/i', $headers['Authorization'], $matches)) {
return $matches[1];
}
}
return null;
}
/**
* Middleware de autenticación
* Retorna los datos del usuario si el token es válido, o false si no
*/
public static function authenticate() {
if (self::$userData !== null) {
return self::$userData; // Ya autenticado
}
// Intentar obtener el token del header
$token = self::getTokenFromHeader();
// Si no está en el header, buscar en cookie
if (!$token && isset($_COOKIE['auth_token'])) {
$token = $_COOKIE['auth_token'];
}
if (!$token) {
return false;
}
$result = self::validateToken($token);
if (!$result['valid']) {
return false;
}
self::$userData = $result['data'];
return self::$userData;
}
/**
* Obtener los datos del usuario autenticado.
* Asume que authenticate() o requireAuth() ya han sido llamados.
*/
public static function getUserData() {
return self::$userData;
}
/**
* Middleware que requiere autenticación
* Redirige al login si no está autenticado
*/
public static function requireAuth($redirectTo = '/login.php') {
$userData = self::authenticate();
if (!$userData) {
header('Location: ' . $redirectTo);
exit;
}
return $userData;
}
/**
* Cargar los permisos de un usuario desde la base de datos
*/
public static function loadUserPermissions($userId) {
try {
$db = getDB();
$stmt = $db->prepare("
SELECT p.nombre
FROM permisos p
INNER JOIN usuarios_permisos up ON p.id = up.permiso_id
WHERE up.usuario_id = ?
");
$stmt->execute([$userId]);
$permisos = $stmt->fetchAll(PDO::FETCH_COLUMN);
return $permisos;
} catch (PDOException $e) {
error_log("Error cargando permisos: " . $e->getMessage());
return [];
}
}
}