117 lines
3.0 KiB
PHP
Executable File
117 lines
3.0 KiB
PHP
Executable File
<?php
|
|
|
|
class JWT {
|
|
private static $secret = '';
|
|
private static $algorithm = 'HS256';
|
|
private static $tokenExpiration = 86400; // 24 horas en segundos
|
|
|
|
private static function getSecret() {
|
|
if (empty(self::$secret)) {
|
|
if (defined('JWT_SECRET')) {
|
|
self::$secret = JWT_SECRET;
|
|
} else {
|
|
self::$secret = 'ibiza_secret_key_change_in_production_2025';
|
|
}
|
|
}
|
|
return self::$secret;
|
|
}
|
|
|
|
private static function getExpiration() {
|
|
if (defined('JWT_EXPIRATION')) {
|
|
return JWT_EXPIRATION;
|
|
}
|
|
return self::$tokenExpiration;
|
|
}
|
|
|
|
public static function encode($payload) {
|
|
$header = json_encode([
|
|
'typ' => 'JWT',
|
|
'alg' => self::$algorithm
|
|
]);
|
|
|
|
$payload = array_merge($payload, [
|
|
'iat' => time(),
|
|
'exp' => time() + self::getExpiration()
|
|
]);
|
|
|
|
$base64UrlHeader = self::base64UrlEncode($header);
|
|
$base64UrlPayload = self::base64UrlEncode(json_encode($payload));
|
|
|
|
$signature = hash_hmac(
|
|
'sha256',
|
|
$base64UrlHeader . "." . $base64UrlPayload,
|
|
self::getSecret(),
|
|
true
|
|
);
|
|
|
|
$base64UrlSignature = self::base64UrlEncode($signature);
|
|
|
|
return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
|
|
}
|
|
|
|
public static function decode($token) {
|
|
$tokenParts = explode('.', $token);
|
|
|
|
if (count($tokenParts) !== 3) {
|
|
return null;
|
|
}
|
|
|
|
list($header, $payload, $signature) = $tokenParts;
|
|
|
|
$validSignature = hash_hmac(
|
|
'sha256',
|
|
$header . "." . $payload,
|
|
self::getSecret(),
|
|
true
|
|
);
|
|
|
|
if (!hash_equals(self::base64UrlEncode($validSignature), $signature)) {
|
|
return null;
|
|
}
|
|
|
|
$decoded = json_decode(self::base64UrlDecode($payload), true);
|
|
|
|
if (isset($decoded['exp']) && $decoded['exp'] < time()) {
|
|
return null;
|
|
}
|
|
|
|
return $decoded;
|
|
}
|
|
|
|
public static function getUserId($token) {
|
|
$decoded = self::decode($token);
|
|
return $decoded['user_id'] ?? null;
|
|
}
|
|
|
|
public static function getUserData($token) {
|
|
return self::decode($token);
|
|
}
|
|
|
|
public static function refreshToken($token) {
|
|
$decoded = self::decode($token);
|
|
|
|
if (!$decoded) {
|
|
return null;
|
|
}
|
|
|
|
// Verificar si está en el período de gracia (última hora)
|
|
if ($decoded['exp'] - time() < 3600) {
|
|
return self::encode([
|
|
'user_id' => $decoded['user_id'],
|
|
'username' => $decoded['username'],
|
|
'role' => $decoded['role']
|
|
]);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static function base64UrlEncode($data) {
|
|
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
|
|
}
|
|
|
|
private static function base64UrlDecode($data) {
|
|
return base64_decode(strtr($data, '-_', '+/'));
|
|
}
|
|
}
|