OAuth 2.0 y autorización JWT en PHP: guía práctica completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a OAuth 2.0 y JWT en PHP

\n

Las aplicaciones web modernas se están alejando cada vez más de la autenticación clásica por sesiones en favor de soluciones más flexibles y escalables. Dos protocolos clave — OAuth 2.0 y JWT (JSON Web Tokens) — se han convertido en el estándar de facto para la autorización en REST API, aplicaciones móviles y arquitectura de microservicios. En este artículo, analizaremos con ejemplos prácticos cómo implementar la autorización OAuth 2.0 y JWT en PHP, utilizando bibliotecas modernas y las mejores prácticas de seguridad.

\n

Aprenderá a configurar un servidor de autorización, emitir y verificar tokens JWT, organizar la emisión de refresh tokens y proteger sus endpoints de API. Todos los ejemplos de código están listos para usar en sus proyectos.

\n\n

Fundamentos del protocolo OAuth 2.0

\n

OAuth 2.0 es un protocolo de autorización que permite a las aplicaciones obtener acceso limitado a los recursos del usuario sin compartir sus credenciales. En el contexto de una aplicación PHP, OAuth 2.0 generalmente se implementa mediante el grant de código de autorización (Authorization Code Grant) o el grant de contraseña (Password Grant) para servicios propios.

\n\n

Roles clave en OAuth 2.0

\n
    \n
  • Resource Owner — el usuario que posee los datos
  • \n
  • Client — la aplicación que solicita acceso (por ejemplo, su frontend PHP)
  • \n
  • Authorization Server — el servidor que emite los tokens
  • \n
  • Resource Server — el servidor que proporciona los recursos protegidos (su API)
  • \n
\n\n

Flujo de obtención de token mediante Authorization Code Grant

\n
    \n
  1. El usuario navega a la página de autorización
  2. \n
  3. Después de iniciar sesión, el usuario es redirigido de vuelta a la aplicación con un código temporal
  4. \n
  5. El servidor PHP intercambia el código por un access_token y un refresh_token
  6. \n
  7. Todas las solicitudes posteriores a la API se realizan con el encabezado Authorization: Bearer <access_token>
  8. \n
\n\n

Implementación de JWT en PHP con la biblioteca firebase/php-jwt

\n

Para trabajar con JWT en PHP, utilizaremos la popular biblioteca firebase/php-jwt. La instalaremos a través de Composer:

\n
composer require firebase/php-jwt
\n\n

Generación de un token JWT

\n

Crearemos una función para emitir un access token con una carga útil (claims):

\n
<?php\nuse Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\nfunction generateAccessToken(int $userId, string $email): string {\n    $secretKey = 'your-256-bit-secret-key-here';\n    $issuedAt = time();\n    $expirationTime = $issuedAt + 3600; // 1 hora\n\n    $payload = [\n        'iss' => 'pythonlib.ru',\n        'iat' => $issuedAt,\n        'exp' => $expirationTime,\n        'sub' => $userId,\n        'email' => $email,\n        'roles' => ['user']\n    ];\n\n    return JWT::encode($payload, $secretKey, 'HS256');\n}
\n\n

Verificación del token JWT

\n

Verificación de la autenticidad del token en cada solicitud a un recurso protegido:

\n
<?php\nfunction validateAccessToken(string $token): ?object {\n    $secretKey = 'your-256-bit-secret-key-here';\n    try {\n        $decoded = JWT::decode($token, new Key($secretKey, 'HS256'));\n        return $decoded;\n    } catch (\\Exception $e) {\n        // Token expirado, no válido o firma incorrecta\n        return null;\n    }\n}
\n\n

Middleware para verificar JWT

\n

Ejemplo de un middleware simple que se puede usar con cualquier framework:

\n
<?php\nfunction authMiddleware(): ?object {\n    $headers = getallheaders();\n    $authHeader = $headers['Authorization'] ?? '';\n\n    if (!preg_match('/Bearer\\s(\\S+)/', $authHeader, $matches)) {\n        http_response_code(401);\n        echo json_encode(['error' => 'Token no proporcionado']);\n        exit;\n    }\n\n    $token = $matches[1];\n    $user = validateAccessToken($token);\n\n    if (!$user) {\n        http_response_code(401);\n                

Blogs

Book Recommendations