🔐 Autenticación con JWT en PHP explicada fácil (con ejemplos reales)


Introducción


Cuando empiezas a crear APIs, hay un momento donde todo cambia:

👉 ya no basta con devolver datos

👉 necesitas controlar quién puede acceder

Y aquí es donde entra uno de los conceptos más importantes en backend moderno:

JWT (JSON Web Token)


JWT se usa en:

  • APIs REST
  • apps móviles
  • dashboards
  • SaaS
  • microservicios
  • autenticación moderna


Pero aquí está el problema:

Muchos tutoriales te enseñan a copiar código…

pero no a entender cómo funciona.


En este post vas a aprender:

  • qué es JWT realmente
  • cómo funciona por dentro
  • cómo generar tokens en PHP
  • cómo validar tokens
  • cómo proteger rutas
  • errores comunes
  • buenas prácticas

👉 todo explicado de forma clara y práctica



🧠 Qué es JWT (explicado fácil)


JWT es un token que representa la identidad de un usuario.

En lugar de usar sesiones en servidor, haces esto:

  1. el usuario hace login
  2. el servidor genera un token
  3. el cliente guarda ese token
  4. el cliente lo envía en cada petición
  5. el servidor valida el token

👉 Si es válido → acceso permitido

👉 Si no → acceso denegado


📦 Estructura de un JWT


Un token tiene 3 partes:

HEADER.PAYLOAD.SIGNATURE


Ejemplo:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...


🔍 Qué contiene cada parte


1. Header

Define el algoritmo:

{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload (datos)


Aquí va la info del usuario:

{
  "user_id": 1,
  "email": "irak@mail.com",
  "exp": 1710000000
}

👉 Importante: esto no está cifrado



3. Signature


Se genera con:

  • header
  • payload
  • clave secreta

👉 Sirve para evitar manipulación



⚙️ Cómo implementar JWT en PHP


📦 Paso 1: instalar librería

La más usada:

composer require firebase/php-jwt


🔑 Paso 2: generar token (login)

<?php
use Firebase\JWT\JWT;

$key = "mi_clave_secreta";

$payload = [
    "user_id" => 1,
    "email" => "irak@mail.com",
    "exp" => time() + 3600 // 1 hora
];

$jwt = JWT::encode($payload, $key, 'HS256');

echo json_encode([
    "token" => $jwt
]);


🔍 Paso 3: validar token

<?php
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$headers = getallheaders();

if (!isset($headers['Authorization'])) {
    http_response_code(401);
    exit("Token requerido");
}

$token = str_replace('Bearer ', '', $headers['Authorization']);

try {
    $decoded = JWT::decode($token, new Key($key, 'HS256'));

    echo json_encode([
        "message" => "Acceso permitido",
        "user" => $decoded
    ]);

} catch (Exception $e) {
    http_response_code(401);
    echo json_encode(["error" => "Token inválido"]);
}


🔐 Cómo proteger rutas con JWT

Ejemplo:

require 'auth.php'; // valida token

👉 Si el token falla → no pasa

👉 Si es válido → continúa


📡 Cómo enviar el token desde frontend


Ejemplo con fetch:

fetch('/api/protegido', {
  headers: {
    "Authorization": "Bearer TOKEN_AQUI"
  }
})


⚠️ Errores comunes con JWT


❌ Guardar datos sensibles en el payload

👉 cualquiera puede leerlo



❌ No validar expiración

👉 riesgo de seguridad



❌ Usar clave débil

👉 fácil de romper



❌ No usar HTTPS

👉 token puede ser interceptado



🔐 Buenas prácticas


  • usar claves seguras
  • usar expiración corta
  • refrescar tokens si hace falta
  • no guardar passwords en JWT
  • usar HTTPS siempre


🧠 JWT vs sesiones (muy importante)


JWT	                    Sesión
stateless	            stateful
no guarda en servidor	sí
escalable	            más simple
ideal APIs              ideal apps clásicas


🧪 Ejemplo real de flujo completo


  1. Usuario login → API genera token
  2. Frontend guarda token
  3. Usuario hace request
  4. API valida token
  5. Devuelve datos


📈 Cuándo usar JWT


✔ APIs

✔ apps móviles

✔ microservicios

✔ SPA


❌ Cuándo NO usar JWT


  • apps simples
  • sin necesidad de escalabilidad
  • proyectos muy pequeños


🧩 Conclusión:


JWT es una de las herramientas más importantes en backend moderno.

Si lo entiendes:

  • puedes proteger APIs
  • puedes escalar sistemas
  • puedes trabajar en proyectos reales

Y eso te pone en otro nivel.







🔗 Siguiente lectura recomendada: