Primer version funcional
This commit is contained in:
116
core/JWT.php
Executable file
116
core/JWT.php
Executable file
@@ -0,0 +1,116 @@
|
||||
<?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, '-_', '+/'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user