1-Autenticación JWT en PHP: Explicación y Ejemplo
Autenticación JWT en PHP: Explicación y Ejemplo
¿Qué es JWT?
JWT (JSON Web Token) es un estándar abierto que permite transmitir información de forma segura entre partes como un objeto JSON. Es muy utilizado para autenticación y autorización en APIs.
¿Por qué usar JWT?
Sin estado (Stateless): El servidor no necesita almacenar sesiones
Seguro: Los tokens están firmados digitalmente
Portable: Funciona en múltiples dominios y aplicaciones
Extensible: Puedes incluir cualquier información en el payload
Estructura de un JWT
Un JWT tiene 3 partes separadas por puntos:
Header: Metadatos sobre el tipo de token y algoritmo
Payload: Los datos que quieres transmitir
Signature: Firma digital para verificar autenticidad
Ejemplo completo de login con JWT
1. Instalación de dependencias
composer require firebase/php-jwt2. Configuración inicial
<?php
require 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
// Configuración
$secret_key = "tu_clave_secreta_super_segura"; // Debe ser larga y segura
$algorithm = 'HS256';
$issuer = "tu_dominio.com";
$audience = "tu_app";
$token_expiration = 3600; // 1 hora en segundos
?>3. Endpoint de Login
<?php
// login.php
require 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Obtener datos del request
$data = json_decode(file_get_contents("php://input"), true);
$username = $data['username'] ?? '';
$password = $data['password'] ?? '';
// Validar credenciales (en un caso real, verificar contra base de datos)
if ($username === 'admin' && $password === 'password123') {
// Credenciales válidas - generar token
$issued_at = time();
$expiration_time = $issued_at + $token_expiration;
$payload = array(
"iss" => $issuer, // Emisor
"aud" => $audience, // Audiencia
"iat" => $issued_at, // Tiempo de emisión
"exp" => $expiration_time, // Tiempo de expiración
"data" => array( // Datos del usuario
"user_id" => 1,
"username" => $username,
"role" => "admin"
)
);
// Generar el token JWT
$jwt = JWT::encode($payload, $secret_key, $algorithm);
// Responder con el token
http_response_code(200);
echo json_encode(array(
"message" => "Login exitoso",
"token" => $jwt,
"expires" => $expiration_time
));
} else {
// Credenciales inválidas
http_response_code(401);
echo json_encode(array("message" => "Credenciales inválidas"));
}
} else {
http_response_code(405);
echo json_encode(array("message" => "Método no permitido"));
}
?>4. Middleware para verificar el token
<?php
// auth_middleware.php
function verifyToken() {
$headers = apache_request_headers();
$auth_header = $headers['Authorization'] ?? $headers['authorization'] ?? '';
if (empty($auth_header)) {
http_response_code(401);
echo json_encode(array("message" => "Token requerido"));
exit;
}
// Extraer el token del header "Bearer {token}"
$token = str_replace('Bearer ', '', $auth_header);
try {
global $secret_key, $algorithm;
// Decodificar y verificar el token
$decoded = JWT::decode($token, new Key($secret_key, $algorithm));
// El token es válido, devolver los datos decodificados
return $decoded;
} catch (Exception $e) {
http_response_code(401);
echo json_encode(array(
"message" => "Token inválido",
"error" => $e->getMessage()
));
exit;
}
}
?>5. Endpoint protegido
<?php
// protected.php
require 'config.php';
require 'auth_middleware.php';
// Verificar el token
$decoded_token = verifyToken();
// Si llegamos aquí, el token es válido
$user_data = $decoded_token->data;
// Responder con datos protegidos
http_response_code(200);
echo json_encode(array(
"message" => "Acceso concedido",
"user_data" => $user_data,
"protected_data" => "Esta información es solo para usuarios autenticados"
));
?>6. Logout (lado del cliente)
<?php
// logout.php
// Para logout, simplemente el cliente debe eliminar el token almacenado
http_response_code(200);
echo json_encode(array("message" => "Logout exitoso - elimina el token del cliente"));
?>Cómo usar la API
1. Login (obtener token)
curl -X POST http://tudominio.com/login.php \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password123"}'2. Acceder a endpoint protegido
curl -X GET http://tudominio.com/protected.php \
-H "Authorization: Bearer {tu_token_jwt}"3. Logout (en el cliente)
Simplemente eliminar el token del almacenamiento local/sessionStorage.
Consideraciones de seguridad
Clave secreta: Debe ser larga y compleja, almacenada de forma segura
HTTPS: Siempre usar HTTPS en producción
Expiración: Tokens con tiempo de vida corto
Almacenamiento: Guardar tokens en HttpOnly cookies o localStorage seguro
Refresh tokens: Implementar sistema de refresh tokens para renovación
Ventajas sobre sesiones tradicionales
Escalabilidad: No requiere almacenamiento en servidor
APIs RESTful: Ideal para arquitecturas stateless
Cross-domain: Funciona bien en aplicaciones con múltiples dominios
Mobile-friendly: Fácil implementación en apps móviles
Este ejemplo proporciona una base sólida para implementar autenticación JWT en tu API PHP.
Comentarios
Publicar un comentario