4.4Crear una API REST y autenticación JWT
Lo esencial en 30 segundos
- REST = recursos + métodos :
GET /api/produits(listar, 200),POST(crear, 201),PUT(modificar),DELETE(suprimir) — JSON en todas partes. - JWT = token firmado autocontenido : emitido al conectarse, devuelto en
Authorization: Bearer …, verificado sin sesión — adaptado al front separado y al móvil. - Reflejo de Riad : secreto JWT en variable de entorno (
.env, nunca en duro), HTTPS indispensable, validación + errores JSON limpios.
Minicaso seguido — Riad abre su catálogo en API
La tienda de Riad quiere una aplicación móvil en Constantine : su catálogo debe salir en JSON, no en HTML. Riad diseña sus endpoints (GET listar/leer, POST crear en 201, PUT, DELETE), devuelve JSON con los buenos códigos, y luego asegura : al conectarse emite un JWT firmado cuyo secreto vive en .env, y cada petición móvil lo devuelve en la cabecera Authorization. Cuando el token falta o está falsificado, la API responde 401 sin exponer los datos. Cuarto hito del hilo : el mismo back-end sirve al sitio y al móvil.
Continuación del caso 4.1-4.3 — Riad desacopla su back-end de sus clientes.
1. La API REST
Una API expone DATOS (JSON) a otros programas : front JavaScript separado (React, Vue), aplicación móvil, otros servicios. El estilo REST : recursos vía URL claras, manipulados por los métodos HTTP según su semántica — GET /api/produits (listar), GET /api/produits/{id} (leer), POST /api/produits (crear, 201), PUT/PATCH /api/produits/{id} (modificar), DELETE /api/produits/{id} (suprimir) — respuestas JSON con los buenos códigos (200, 201, 400, 401, 404). En PHP se puede improvisar a mano (router, json_encode, cabeceras, códigos) pero en real se usan las herramientas de API de los frameworks (enrutamiento de API, serialización, validación).
2. La autenticación por tokens (JWT)
HTTP es sin estado y la API sirve a clientes variados (sin cookies de navegador garantizadas) : nos autenticamos por tokens. El JWT (JSON Web Token) : tras conexión exitosa, el servidor emite un token FIRMADO criptográficamente (que prueba la identidad sin ser falsificable) ; el cliente lo guarda y lo devuelve en cada petición (Authorization: Bearer <token>) ; el servidor VERIFICA la firma — sin guardar sesión, de ahí « autocontenido ». Ideal para front separado, móvil, multiservidor. Los frameworks ofrecen sistemas de auth de API robustos (no improvisar su cripto en prod).
Seguridad de API no negociable : tokens seguros de corta duración, HTTPS indispensable (los tokens circulan), validación de entradas, autorización (los derechos, no solo la identidad), errores JSON coherentes (códigos + mensajes, sin fugas), rate limiting. Una API bien diseñada es previsible, profesional y segura — el entregable de las arquitecturas back-end + front/móvil desacoplados.
El 200 universal (escena a no reproducir)
Moraleja : 201 cuando está creado, 404 cuando está ausente, 400 cuando es inválido — el JSON dice qué, el código dice cómo.
🔎 Ejemplo concreto — 🔎 Ejemplo concreto — Los endpoints del catálogo de Riad
La tabla que Riad muestra encima de su pantalla :
GET /api/produits → listar (200)
GET /api/produits/{id} → leer (200, 404 si ausente)
POST /api/produits → crear (201, 400 si inválido)
PUT /api/produits/{id} → modificar (200, 404 si ausente)
DELETE /api/produits/{id} → suprimir (204)
Auth → Authorization: Bearer (401 si ausente/inválido)
Lectura : cinco líneas, cinco parejas método + URL + código.
Lección : la acción viene del método, la prueba de identidad del token.
Vocabulario de la sección
- API REST
- Interfaz que expone datos (JSON) a otros programas (front, móvil, servicios) ; recursos vía URL, métodos HTTP semánticos, códigos de estado.
Ejemplo sencillo: El catálogo JSON de Riad sirve al sitio y a la aplicación móvil.
Lo que no es: una página HTML generada del lado del servidor únicamente.
Reflejo: recurso + método + código esperado para cada endpoint.
- Recursos y métodos (API)
- GET listar/leer, POST crear (201), PUT/PATCH modificar, DELETE suprimir ; JSON con los buenos códigos (200, 201, 400, 401, 404…).
Ejemplo sencillo: Riad crea en POST → 201, lee un ausente → 404.
Lo que no es: todo en POST con 200 incluso en error.
Reflejo: nunca 200 para un error, nunca verbo en la URL.
- Autenticación por tokens
- Para las API (sin estado, clientes variados) : tras la conexión, token devuelto en cada petición (Authorization) y verificado por el servidor.
Ejemplo sencillo: El móvil de Riad devuelve su token en cada llamada al catálogo.
Lo que no es: una sesión cookie supuesta disponible en todas partes.
Reflejo: cada ruta sensible exige y verifica el token.
- JWT (JSON Web Token)
- Token FIRMADO criptográficamente, autocontenido (sin almacenamiento en el servidor), devuelto en cada petición y verificado. Adaptado al front separado y al móvil.
Ejemplo sencillo: Riad emite un JWT al conectarse y verifica su firma después.
Lo que no es: un identificador previsible pasado en query string.
Reflejo: firma verificada, corta duración, nada sensible dentro.
- Seguridad de API
- Tokens seguros, HTTPS indispensable, validación de entradas, autorización (derechos), errores JSON limpios, rate limiting.
Ejemplo sencillo: Riad acumula HTTPS + validación + 401/403 limpios + límite de ritmo.
Lo que no es: una API sin HTTPS que acepta todo y responde 200.
Reflejo: el token circula : debe viajar cifrado y expirar rápido.
En la práctica — En la práctica — Exponer datos vía una API REST
- Diseñad los endpoints de un recurso según REST : GET listar/leer, POST crear (201), PUT modificar, DELETE suprimir — respuestas JSON.
- Devolved JSON con los buenos códigos (json_encode + cabeceras a mano, o herramientas de API de un framework).
- Asegurad por JWT : token firmado emitido al conectarse (secreto en .env), verificado en cada petición (Authorization).
- Añadid HTTPS, validación, autorización, errores JSON coherentes y rate limiting.
Guion listo para decir — presentar su API al cliente móvil (30 s)
« Soy Riad : nuestra API expone el catálogo en JSON — GET para leer, POST en 201 para crear, PUT y DELETE, con los buenos códigos. La conexión emite un JWT firmado cuyo secreto vive en .env, cada petición lo envía en Authorization, y todo circula en HTTPS. »
Para decir en demo ; mostrad la tabla de endpoints y una llamada con token.
Modelo copiar-pegar — API PHP + JWT vía el entorno (código probado)
'Configuración del servidor ausente']); exit; }
header('Content-Type: application/json');
$methode = $_SERVER['REQUEST_METHOD'];
$chemin = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// Conexión : verifica (hash en real), emite un JWT corto
if ($methode === 'POST' && $chemin === '/api/connexion') {
$corps = json_decode(file_get_contents('php://input'), true) ?? [];
if (empty($corps['email']) || empty($corps['motDePasse'])) {
http_response_code(400); echo json_encode(['error' => 'Correo y contraseña requeridos']); exit;
}
$jeton = JWT::encode(['sub' => $corps['email'], 'iat' => time(), 'exp' => time() + 3600], $secret, 'HS256');
echo json_encode(['jeton' => $jeton]); exit;
}
// Ruta protegida : verifica el JWT (401 si ausente/inválido)
if ($methode === 'GET' && $chemin === '/api/produits') {
$entete = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (!str_starts_with($entete, 'Bearer ')) { http_response_code(401); echo json_encode(['error' => 'Token ausente']); exit; }
try {
JWT::decode(substr($entete, 7), new Key($secret, 'HS256'));
} catch (Exception $e) { http_response_code(401); echo json_encode(['error' => 'Token inválido']); exit; }
echo json_encode([['nom' => 'Couscoussier', 'prix' => 2500]]); exit;
}
http_response_code(404); echo json_encode(['error' => 'No encontrado']);
Prototipo local
Endpoints JSON a mano (router + json_encode) : convenciones REST desde el inicio, no cuestan nada.
Aplicación real
Como Riad : herramientas de API del framework, JWT vía .env, HTTPS, validación y rate limiting.
API multicliente
Un solo back-end para web + móvil : versionad (/api/v1/) para evolucionar sin romper.
Datos sensibles
Duración de token corta, revocación prevista, nada sensible en el payload — y auditoría antes de prod.
.env fuera de Git), nunca en duro en el código ; HTTPS obligatorio (los tokens circulan en claro si no) ; duración corta y validación sistemática. Ejemplos con datos ficticios únicamente — ningún secreto real. Contenido pedagógico, no una auditoría de seguridad.✓ Buenas prácticas
- Diseñar en recursos + métodos + buenos códigos.
- Autenticar por JWT verificado en cada petición.
- Imponer HTTPS, validación y errores JSON limpios.
✗ Errores frecuentes
- Devolver todo en 200 incluso en error.
- Exponer una API sin HTTPS.
- Improvisar su cripto JWT en producción.
Puntos clave
- API REST = DATOS JSON para front/móvil/servicios : RECURSOS vía URL, MÉTODOS semánticos, CÓDIGOS justos.
- A mano (router, json_encode) o vía FRAMEWORK (enrutamiento de API, serialización, validación).
- JWT : token FIRMADO autocontenido (Authorization: Bearer), verificado sin sesión — adaptado a clientes variados.
- SEGURIDAD : secreto en .env, HTTPS, validación, autorización, errores limpios, rate limiting.
Desafío 48h — aplicad mañana
Exponed 1 recurso en JSON (5 endpoints, buenos códigos) + conexión JWT (secreto en .env) y verificad el 401 sin token.
- Puedo citar los 5 endpoints y sus códigos.
- Sé explicar JWT frente a sesiones.
- Tengo 1 ruta protegida probada con y sin token.
Preguntas frecuentes
¿Por qué construir una API en lugar de un sitio que genera HTML?
Cuando el consumidor no es solo un navegador : aplicación front separada (React/Vue/Angular, SPA interactiva), aplicación móvil (que solo consume JSON), varios clientes (web + móvil + socios sobre UN mismo back-end reutilizado), arquitecturas de servicios/microservicios. Si no, el sitio clásico (HTML servidor) sigue más simple. Riad elige la API en cuanto un móvil o un front desacoplado entra en juego.
¿Qué es un JWT — y por qué tokens en lugar de sesiones para las API?
Sesiones : estado del lado del servidor + cookies navegador — bien para un sitio clásico, pero ligadas al navegador y complicadas a escala multiservidor. JWT : token firmado emitido al conectarse, guardado del lado del cliente, devuelto en Authorization y verificado por firma — sin estado en el servidor, adaptado a clientes variados (móvil, servicios) y al paso a escala. Vigilancias : clave protegida (nunca en duro), corta duración/refresh, nada sensible en el payload, HTTPS.
¿Por qué tokens (JWT) en lugar de sesiones para una API?