Implementar JWT (Json Web Tokens) en PHP

Tiempo de lectura: 4 minutos

En este tutorial, te mostraré cómo implementar JSON Web Tokens (JWT) en PHP. JWT es una forma segura y fácil de autenticar y autorizar usuarios en aplicaciones web.

Paso 1: Instalar dependencias

Para comenzar, necesitamos instalar las dependencias necesarias para trabajar con JWT en PHP. Utilizaremos la biblioteca «firebase/php-jwt» que proporciona soporte para JWT en PHP.

Puedes instalar esta biblioteca utilizando Composer. Si no tienes Composer instalado, puedes descargarlo desde su sitio web oficial. Una vez que tienes Composer instalado, crea un nuevo proyecto y agrega la biblioteca de JWT ejecutando los siguientes comandos en tu terminal:

composer init
composer require firebase/php-jwt

Estos comandos crean un nuevo proyecto de Composer y agregan la biblioteca de JWT como una dependencia.

Paso 2: Generar un token JWT

Una vez que hemos instalado las dependencias, podemos comenzar a trabajar con JWT. Lo primero que debemos hacer es generar un token JWT.

Para hacerlo, primero debemos definir un conjunto de reclamaciones que se incluirán en el token. Las reclamaciones son pares de clave-valor que se utilizan para transmitir información sobre el usuario y la sesión. Algunas reclamaciones comunes son «sub» (sujeto), «iat» (tiempo de emisión), «exp» (tiempo de expiración) y «iss» (emisor).

A continuación, crearemos una función llamada «generateToken» que generará un token JWT con las reclamaciones especificadas:

require_once __DIR__ . '/vendor/autoload.php';

use Firebase\JWT\JWT;

function generateToken($user_id) {
  $key = 'secret_key';
  $payload = array(
    'iss' => 'localhost',
    'sub' => $user_id,
    'iat' => time(),
    'exp' => time() + (60 * 60 * 24)
  );

  $token = JWT::encode($payload, $key);
  return $token;
}

En este ejemplo, estamos definiendo una clave secreta llamada «secret_key» que se utilizará para firmar el token. También estamos incluyendo las reclamaciones «iss», «sub», «iat» y «exp». La reclamación «sub» se establece en el ID de usuario y las reclamaciones «iat» y «exp» se establecen en el tiempo actual y un día en el futuro, respectivamente.

Finalmente, utilizamos la biblioteca de JWT para codificar el conjunto de reclamaciones en un token JWT firmado.

Paso 3: Verificar un token JWT

Ahora que hemos generado un token JWT, necesitamos verificarlo antes de permitir que un usuario acceda a recursos protegidos. Para hacerlo, crearemos una función llamada «verifyToken» que verificará la firma del token y devolverá los datos de usuario si el token es válido:

function verifyToken($token) {
  $key = 'secret_key';
  try {
    $decoded = JWT::decode($token, $key, array('HS256'));
    $user_id = $decoded->sub;
    return array('success' => true, 'user_id' => $user_id);
  } catch (Exception $e) {
    return array('success' => false, 'error' => $e->getMessage());
  }
}

En este ejemplo, estamos utilizando la biblioteca de JWT para decodificar el token y verificar su firma utilizando la clave secreta «secret_key».

Si el token es válido, extraemos el ID de usuario de la reclamación «sub» y lo devolvemos junto con un indicador de éxito. Si el token no es válido, capturamos la excepción generada por la biblioteca de JWT y devolvemos un mensaje de error.

Paso 4: Integrar JWT en una aplicación web

Ahora que hemos generado y verificado un token JWT, podemos integrarlo en una aplicación web. Para hacerlo, crearemos un formulario de inicio de sesión que solicite al usuario su correo electrónico y contraseña.

Cuando el usuario envíe el formulario, validaremos sus credenciales y generaremos un token JWT si son válidas. Luego, almacenaremos el token en una cookie y redireccionaremos al usuario a una página protegida.

En la página protegida, verificaremos el token JWT almacenado en la cookie y permitiremos que el usuario acceda a los recursos protegidos si el token es válido.

A continuación, te muestro un ejemplo de cómo integrar JWT en una aplicación web utilizando PHP:

require_once __DIR__ . '/vendor/autoload.php';

use Firebase\JWT\JWT;

// Función para generar un token JWT
function generateToken($user_id) {
  $key = 'secret_key';
  $payload = array(
    'iss' => 'localhost',
    'sub' => $user_id,
    'iat' => time(),
    'exp' => time() + (60 * 60 * 24)
  );

  $token = JWT::encode($payload, $key);
  return $token;
}

// Función para verificar un token JWT
function verifyToken($token) {
  $key = 'secret_key';
  try {
    $decoded = JWT::decode($token, $key, array('HS256'));
    $user_id = $decoded->sub;
    return array('success' => true, 'user_id' => $user_id);
  } catch (Exception $e) {
    return array('success' => false, 'error' => $e->getMessage());
  }
}

// Si el formulario de inicio de sesión se envía
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['email']) && isset($_POST['password'])) {
  $email = $_POST['email'];
  $password = $_POST['password'];

  // Verificar las credenciales del usuario
  if ($email === 'usuario@example.com' && $password === 'contraseña') {

    // Generar un token JWT para el usuario
    $token = generateToken(123);

    // Almacenar el token en una cookie
    setcookie('token', $token, time() + (60 * 60 * 24), '/');

    // Redireccionar al usuario a la página protegida
    header('Location: protegida.php');
    exit();
  } else {
    echo 'Credenciales inválidas.';
  }
}

// Si el usuario intenta acceder a la página protegida
if ($_SERVER['REQUEST_URI'] === '/protegida.php') {

  // Verificar el token JWT almacenado en la cookie
  if (isset($_COOKIE['token'])) {
    $token = $_COOKIE['token'];
    $result = verifyToken($token);

    // Permitir que el usuario acceda a los recursos protegidos si el token es válido
    if ($result['success'] === true) {
      echo '¡Bienvenido, usuario #' .$result['user_id'] . '!';
} else {
// Redireccionar al usuario a la página de inicio de sesión si el token es inválido
header('Location: inicio.php');
exit();
}
} else {
// Redireccionar al usuario a la página de inicio de sesión si no hay token
header('Location: inicio.php');
exit();
}
}

En este ejemplo, hemos creado dos funciones llamadas generateToken y verifyToken que se encargan de generar y verificar tokens JWT, respectivamente. También hemos creado un formulario de inicio de sesión que solicita al usuario su correo electrónico y contraseña.

Cuando el usuario envía el formulario, verificamos sus credenciales y generamos un token JWT si son válidas. Luego, almacenamos el token en una cookie y redireccionamos al usuario a una página protegida llamada «protegida.php».

En la página protegida, verificamos el token JWT almacenado en la cookie y permitimos que el usuario acceda a los recursos protegidos si el token es válido. Si el token es inválido o no está presente, redireccionamos al usuario de regreso a la página de inicio de sesión.

Conclusión

En resumen, JWT es una forma segura y eficiente de autenticar y autorizar usuarios en aplicaciones web y móviles. En este tutorial, hemos aprendido cómo generar y verificar tokens JWT utilizando PHP y la biblioteca de JWT de Firebase.

Recuerda que, al implementar JWT en tu aplicación, es importante mantener tu clave secreta segura y usar algoritmos de cifrado fuertes para proteger tus tokens JWT. También debes tener en cuenta las mejores prácticas de seguridad, como el uso de HTTPS y la validación de entradas de usuario para evitar ataques de inyección de código.

Espero que este tutorial te haya sido útil y te ayude a implementar JWT en tus próximas aplicaciones web y móviles.

Deja un comentario