Tokens JWT en PHP: Guía completa de implementación
\n\nJWT (JSON Web Token) es un estándar abierto (RFC 7519) para la creación de tokens de acceso basados en formato JSON. En PHP, JWT se utiliza ampliamente para implementar autenticación sin estado (stateless authentication) en APIs REST, aplicaciones de una sola página (SPA) y microservicios.
\n\nEn este artículo, analizaremos en detalle cómo trabajar con tokens JWT en PHP: desde la instalación de la librería hasta la creación, verificación y renovación de tokens.
\n\n¿Qué es JWT y por qué es necesario?
\n\nJWT consta de tres partes separadas por puntos:
\n\n- \n
- Header (encabezado) — contiene el tipo de token (JWT) y el algoritmo de firma (por ejemplo, HS256 o RS256). \n
- Payload (carga útil) — contiene las declaraciones (claims): identificador de usuario, rol, hora de emisión (iat), fecha de vencimiento (exp) y otros datos. \n
- Signature (firma) — se crea mediante el hash del encabezado y la carga útil utilizando una clave secreta. \n
Principales ventajas de JWT:
\n- \n
- No requiere almacenar sesiones en el servidor (stateless). \n
- Puede contener cualquier dato (por ejemplo, el rol del usuario). \n
- Funciona con diferentes dominios y aplicaciones móviles. \n
- Se verifica fácilmente sin consultar la base de datos. \n
Instalación de la librería firebase/php-jwt
\n\nPara trabajar con JWT en PHP, usaremos la librería popular firebase/php-jwt. La instalación se realiza a través de Composer:
composer require firebase/php-jwt\n\nDespués de la instalación, aparecerá la carga automática de Composer en el proyecto, que debe incluirse:
\n\nrequire_once 'vendor/autoload.php';\n\nuse Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\nCreación de un token JWT
\n\nPara crear un token, es necesario definir una clave secreta ($secretKey) y formar el payload. Ejemplo:
use Firebase\\JWT\\JWT;\n\n$secretKey = 'your-256-bit-secret-key-here';\n$issuedAt = time();\n$expirationTime = $issuedAt + 3600; // el token vive 1 hora\n\n$payload = [\n 'iss' => 'pythonlib.ru', // emisor\n 'iat' => $issuedAt, // hora de emisión\n 'exp' => $expirationTime, // fecha de vencimiento\n 'sub' => 123, // identificador de usuario\n 'role' => 'admin' // datos personalizados\n];\n\n$jwt = JWT::encode($payload, $secretKey, 'HS256');\necho $jwt;\n\nEl resultado será una cadena como: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJweXRob25saWIucnUiLCJpYXQiOjE3Mjg0MDAwMDAsImV4cCI6MTcyODQwMzYwMCwic3ViIjoxMjMsInJvbGUiOiJhZG1pbiJ9.signature
Verificación y decodificación de JWT
\n\nAl recibir un token del cliente (por ejemplo, del encabezado Authorization: Bearer <token>), es necesario verificarlo:
use Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\n$secretKey = 'your-256-bit-secret-key-here';\n$jwt = $_SERVER['HTTP_AUTHORIZATION'] ?? '';\n\ntry {\n $decoded = JWT::decode($jwt, new Key($secretKey, 'HS256'));\n $userId = $decoded->sub;\n $role = $decoded->role;\n \n echo "Usuario #{$userId} con rol {$role} autorizado.";\n} catch (\\Exception $e) {\n http_response_code(401);\n echo "Error: " . $e->getMessage();\n}\n\nImportante: la librería verifica automáticamente la fecha de vencimiento del token (exp) y la hora de emisión (iat). Si el token ha expirado o no es válido, se lanzará una excepción.
\n\nRenovación de JWT (Refresh Token)
\n\nPara aumentar la seguridad, los JWT suelen tener una vida corta (15–60 minutos). Para sesiones largas, se utiliza un Refresh Token, un token separado que se almacena en la base de datos y permite obtener un nuevo Access Token sin necesidad de volver a ingresar usuario/contraseña.
\n\nEjemplo de implementación de refresh:
\n\nfunction refreshAccessToken(string $ref También en la biblioteca
Envío de correo electrónico en PHP: PHPMailer, SwiftMailer y mail() — guía completa
Procesamiento de JSON en Swift: Codable, JSONSerialization y ejemplos prácticos
ORM para Swift (iOS/macOS): comparación y ejemplos de uso
Geolocalización y mapas en Go: revisión de bibliotecas y ejemplos de código