OAuth 2.0 y autorización JWT en PHP: guía 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: ¿por qué se necesitan OAuth 2.0 y JWT en PHP?

Las aplicaciones web modernas rara vez funcionan de forma aislada. Los usuarios esperan un inicio de sesión único a través de Google, Facebook o GitHub, y los desarrolladores esperan un intercambio seguro de datos entre microservicios. Dos protocolos clave — OAuth 2.0 (delegación de acceso) y JWT (formato de token compacto) — se han convertido en el estándar de facto. En este artículo, analizaremos cómo implementar la autorización OAuth 2.0 y JWT en PHP desde cero, utilizando solo las capacidades integradas del lenguaje y bibliotecas populares. Obtendrá ejemplos de código listos para usar para la integración con proveedores externos y la creación de su propio sistema de autenticación.



1. Fundamentos de OAuth 2.0: flujos y roles

OAuth 2.0 es un protocolo de autorización que permite a aplicaciones de terceros obtener acceso limitado a los recursos del usuario sin transmitir la contraseña. En él participan cuatro roles:

  • Resource Owner — el usuario propietario de los datos.
  • Client — su aplicación PHP que solicita acceso.
  • Authorization Server — el servidor que emite tokens (por ejemplo, Google).
  • Resource Server — la API que proporciona datos mediante el token.

El flujo más popular para aplicaciones web es Authorization Code Grant. Es seguro porque el token se transmite a través de la parte del servidor, no a través del navegador. Veamos la implementación en PHP.



1.1. Registro de la aplicación y obtención de Client ID/Secret

Antes de escribir código, registre la aplicación en el proveedor (por ejemplo, en Google Cloud Console). Obtendrá client_id y client_secret, y configurará el redirect URI (por ejemplo, https://sursitio.es/callback.php).



1.2. Implementación del flujo Authorization Code en PHP

Crearemos dos archivos: login.php (redirección al servidor de autorización) y callback.php (procesamiento de la respuesta).



Archivo login.php

<?phpsession_start();

$client_id = 'SU_CLIENT_ID';$redirect_uri = 'https://sursitio.es/callback.php';$state = bin2hex(random_bytes(16)); // protección contra CSRF$_SESSION['oauth_state'] = $state;

$params = http_build_query([ 'client_id' => $client_id, 'redirect_uri' => $redirect_uri, 'response_type' => 'code', 'scope' => 'openid email profile', 'state' => $state,]);

header('Location: https://accounts.google.com/o/oauth2/v2/auth?' . $params);exit;?>


Archivo callback.php

<?phpsession_start();

// Verificación de state (CSRF)if ($_GET['state'] !== $_SESSION['oauth_state']) { die('Error: state no válido');}

$client_id = 'SU_CLIENT_ID';$client_secret = 'SU_CLIENT_SECRET';$redirect_uri = 'https://sursitio.es/callback.php';

// Intercambio de código por token$ch = curl_init('https://oauth2.googleapis.com/token');curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'code' => $_GET['code'], 'client_id' => $client_id, 'client_secret' => $client_secret, 'redirect_uri' => $redirect_uri, 'grant_type' => 'authorization_code',]));curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$response = curl_exec($ch);curl_close($ch);

$data = json_decode($response, true);$access_token = $data['access_token'] ?? null;

// Obtención del perfil del usuario$ch = curl_init('https://www.googleapis.com/oauth2/v2/userinfo');curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $access_token]);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$userInfo = json_decode(curl_exec($ch), true);curl_close($ch);

echo 'Hola, ' . htmlspecialchars($userInfo['email']);?>

Importante: Siempre verifique el parámetro state. Protege contra la falsificación de solicitudes (CSRF).



2. JW

Blogs

Book Recommendations