Al cerrar el módulo 7 dejamos una pregunta incómoda sobre la mesa. La función comprarEntradas de src/repositorios/compras-sql.js resuelve la sobreventa con una transacción impecable, bloquea la fila de la sesión, descuenta el aforo y emite las entradas. Y recibe un usuarioId… que llega en el cuerpo de la petición. Es decir: de lo que el cliente quiera enviar. Cualquiera puede comprar en nombre de Lucía, consultar los pedidos de Marc, publicar un evento en el Teatro Almendra sin ser su organizador o anular entradas ajenas.
En este módulo llenamos ese hueco. Y empezamos por lo que casi nadie explica bien: qué es exactamente autenticar, en qué se diferencia de autorizar, por qué HTTP nos lo pone difícil, y qué estrategias existen para resolverlo. Esta lección no escribe casi código: construye el mapa mental sin el cual las cinco lecciones siguientes son recetas que se copian sin entender.
Contenido
- Autenticación frente a autorización
- Factores de autenticación y MFA
- El problema central: HTTP no tiene estado
- Estrategias para mantener la identidad entre peticiones
- Cookies explicadas de verdad
- El modelo de amenazas de Escena Viva
- Por qué no se implementa criptografía propia
- El diseño elegido para Escena Viva
- Datos personales y RGPD
- Errores comunes y consejos
- Ejercicios
- Conclusión
- Autenticación frente a autorización
Son dos preguntas distintas que se hacen en momentos distintos.
| Autenticación | Autorización | |
|---|---|---|
| Pregunta | ¿Quién eres? | ¿Qué puedes hacer? |
| Momento | Al entrar (y en cada petición, al verificar la credencial) | En cada acción concreta |
| Resultado | Una identidad: usuario 64f…, rol organizador |
Un permiso: sí / no |
| Fallo típico | Credencial inválida | Identidad válida pero sin permiso |
| Código HTTP | 401 Unauthorized (mal nombrado: significa «no autenticado») | 403 Forbidden |
En Escena Viva la diferencia es muy concreta:
- Autenticación: Lucía escribe
[email protected]y su contraseña. El servidor comprueba que la contraseña coincide con lo que tiene guardado y concluye: esta petición viene de Lucía. - Autorización: Lucía, ya identificada, pide
GET /api/pedidos/ped-042. El servidor comprueba que ese pedido es suyo. Si es de Marc, la respuesta es 403 (o 404, ya veremos por qué a veces conviene).
Confundirlas produce agujeros reales. Los dos errores clásicos:
- Autenticar y dar por hecho el permiso. «Si ha iniciado sesión, es que puede.» Así nace el fallo más común de las APIs:
GET /api/pedidos/:iddevuelve el pedido a cualquier usuario autenticado que adivine el identificador. Se llama referencia directa insegura a objetos (IDOR), y lo atacamos en la lección 08-05. - Autorizar sin autenticar bien. Confiar en un
rolque llega del cliente, o en unusuarioIddel cuerpo —exactamente lo que hace hoycomprarEntradas—. La autorización se apoya sobre la autenticación: si la base es de papel, el edificio también.
Hay un tercer concepto que conviene nombrar para no mezclarlo: identificación es decir quién eres (el correo); autenticación es demostrarlo (la contraseña). Un identificador nunca es una credencial. Enviar solo usuarioId es identificación pura, y por eso hoy la API es indefendible.
- Factores de autenticación y MFA
Un factor es una categoría de prueba. Hay tres clásicas:
| Factor | Qué es | Ejemplos | Debilidad principal |
|---|---|---|---|
| Algo que sabes | Conocimiento secreto | Contraseña, PIN, respuesta secreta | Se reutiliza, se filtra, se adivina |
| Algo que tienes | Posesión de un objeto | Móvil con app TOTP, llave FIDO2, tarjeta | Se pierde o se roba; el SMS se intercepta (SIM swapping) |
| Algo que eres | Rasgo biométrico | Huella, cara | No se puede cambiar si se compromete; suele desbloquear un factor local, no viajar por la red |
MFA (autenticación multifactor) es usar factores de categorías distintas. Contraseña + código TOTP es MFA. Contraseña + pregunta secreta no lo es: ambos son «algo que sabes», y ambos se filtran en la misma base de datos.
Ordenados por robustez real, de menos a más: SMS < correo electrónico < TOTP (aplicación de códigos) < llave física FIDO2/WebAuthn. El SMS es mejor que nada, pero es el eslabón que rompen los ataques dirigidos.
En Escena Viva implementaremos el primer factor bien hecho (contraseña, lección 08-02) y dejaremos el segundo factor documentado como extensión natural: la cuenta de un administrador que puede anular entradas y cambiar roles es exactamente el sitio donde el MFA deja de ser opcional.
- El problema central: HTTP no tiene estado
HTTP es un protocolo sin estado: cada petición es independiente y el servidor no recuerda nada de la anterior. Es una virtud de diseño (permite escalar, balancear, reintentar), pero significa que:
Aunque Lucía se identifique en
POST /auth/login, la siguiente peticiónPOST /api/comprasllega como si el servidor no la hubiera visto nunca.
La única salida es que cada petición transporte una prueba de identidad. Toda la autenticación web se reduce a responder tres preguntas sobre esa prueba:
- ¿Dónde se guarda en el cliente? (cookie, memoria de JavaScript, almacén nativo)
- ¿Cómo viaja? (cookie automática, cabecera
Authorization) - ¿Cómo la verifica el servidor? (buscándola en un almacén, o comprobando una firma)
Las estrategias que vienen a continuación son combinaciones distintas de esas tres respuestas.
- Estrategias para mantener la identidad entre peticiones
| Estrategia | Cómo viaja | Estado en servidor | Ventajas | Inconvenientes | Cuándo elegirla |
|---|---|---|---|---|---|
| Básica HTTP | Authorization: Basic base64(usuario:clave) en cada petición |
Ninguno | Trivial de implementar | Manda la contraseña una y otra vez; sin cierre de sesión; sin caducidad; inutilizable sin TLS | Casi nunca en producción; herramientas internas y pruebas rápidas |
| Sesión de servidor + cookie | Cookie con un identificador aleatorio, enviada por el navegador automáticamente | Sí: la sesión vive en el servidor | Revocación instantánea; la cookie no revela nada; madura y bien entendida | Estado compartido (necesita Redis con varios procesos); vulnerable a CSRF si no se protege; incómoda entre dominios | Aplicaciones web renderizadas en servidor y SPAs del mismo sitio |
| Token autocontenido (JWT) | Authorization: Bearer <token> |
No (el token se autoverifica) | Sin estado, escala fácil; vale entre dominios y para móviles; útil entre microservicios | No se puede revocar sin añadir estado; si se guarda mal en el navegador, el XSS lo roba; carga útil visible | APIs consumidas por móvil, SPAs entre dominios, servicio a servicio |
| Clave de API | Cabecera propia (X-API-Key) o Authorization |
Sí (tabla de claves) | Simple para integraciones; fácil de rotar y revocar por cliente | Identifica una aplicación, no a una persona; sin caducidad natural; se filtra en repositorios | Integraciones máquina a máquina, webhooks, servicios internos |
| OAuth 2.0 / OpenID Connect | Token emitido por un tercero (Google, GitHub, Auth0) | Depende del flujo | Delega contraseñas al proveedor; SSO; consentimiento granular | Complejo; dependencia de un tercero; muchos flujos y muchas formas de equivocarse | «Entrar con Google», acceso a APIs de terceros, identidad corporativa |
Y la pregunta práctica, respondida sin ambigüedad:
- App móvil nativa: tokens (JWT de acceso corto + refresco en el almacén seguro del sistema). Las cookies encajan mal fuera del navegador.
- Web con servidor que renderiza HTML: sesiones de servidor con cookie. Es la opción más segura y sencilla; el navegador ya sabe hacer su parte.
- Servicio a servicio: claves de API o credenciales de cliente de OAuth 2.0, con rotación y ámbito reducido. Nunca la contraseña de una persona.
- SPA + API del mismo sitio: cualquiera de las dos; sesiones si es un único origen, tokens si hay varios clientes.
Escena Viva es una API con front-end estático y aspiraciones de app móvil. Por eso acabará en JWT, pero con la cookie recuperada donde de verdad importa (el token de refresco).
- Cookies explicadas de verdad
Todo lo que viene después se apoya en cookies, así que conviene entenderlas al detalle. Una cookie es un par nombre/valor que el servidor pide al navegador que guarde y reenvíe automáticamente.
HTTP/1.1 200 OK
Set-Cookie: sid=Zk9x3Qb7...; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=1800
Content-Type: application/jsonA partir de ahí, el navegador incluye por su cuenta:
Ese automatismo es la gran ventaja de las cookies (no hay que programar nada en el cliente) y también su gran peligro (se envían aunque la petición la origine otra web: eso es CSRF).
| Atributo | Qué hace | Ataque que mitiga |
|---|---|---|
HttpOnly |
JavaScript no puede leerla (document.cookie no la ve) |
XSS: aunque inyecten un script, no pueden exfiltrar la cookie |
Secure |
Solo viaja por HTTPS | Interceptación en red (Wi-Fi abierta, proxy) |
SameSite=Strict |
No se envía en ninguna petición originada por otro sitio | CSRF (máxima protección; rompe la navegación desde enlaces externos) |
SameSite=Lax |
Se envía en navegaciones de nivel superior con GET, no en POST ni en peticiones en segundo plano |
CSRF en el 95 % de los casos, sin romper enlaces entrantes |
SameSite=None |
Se envía siempre; obliga a Secure |
Ninguno: es para escenarios entre dominios y exige defensa CSRF explícita |
Domain |
Amplía la cookie a subdominios (Domain=escenaviva.test) |
Omitirlo la limita al host exacto: menos alcance, menos riesgo |
Path |
Limita a qué rutas se envía (Path=/auth/refrescar) |
Reduce la exposición del token de refresco |
Max-Age / Expires |
Caducidad. Sin ellos, la cookie es de sesión y muere al cerrar el navegador | Limita la ventana de una cookie robada |
Prefijo __Host- |
El navegador exige Secure, Path=/ y sin Domain |
Impide que un subdominio comprometido plante cookies en el dominio padre |
Tres reglas que aplicaremos sin excepción:
- Toda cookie de autenticación lleva
HttpOnlyySecure. SameSite=Laxpor defecto;Nonesolo con una razón escrita y protección CSRF adicional.- La cookie nunca contiene datos del usuario, solo un identificador opaco o un token firmado.
- El modelo de amenazas de Escena Viva
Modelar amenazas es preguntarse, antes de escribir código: ¿quién ataca, qué quiere y qué pasa si lo consigue?
| Atacante | Qué quiere | Cómo lo intentaría hoy | Impacto |
|---|---|---|---|
| Revendedor | Acaparar entradas del Festival de Jazz | Automatizar POST /api/compras sin límite |
Aforo agotado en segundos; pérdida de reputación |
| Curioso con la API abierta | Ver pedidos de otros | GET /api/pedidos/ped-001, ped-002… |
Fuga de datos personales; incidente RGPD |
| Suplantador | Comprar en nombre de Lucía | Enviar usuarioId de Lucía en el cuerpo |
Cargos indebidos, entradas robadas |
| Competidor de una sala | Publicar o alterar eventos ajenos | POST /api/eventos sin ser organizador de esa sala |
Sabotaje del catálogo |
| Automatización de credenciales | Entrar con contraseñas filtradas de otros sitios | Miles de POST /auth/login |
Cuentas comprometidas en masa |
Y los ataques que hay que conocer por su nombre, porque las lecciones siguientes se refieren a ellos constantemente:
- XSS (Cross-Site Scripting): se inyecta JavaScript en una página y se ejecuta con los permisos del usuario. Es el motivo de
HttpOnlyy de no guardar tokens enlocalStorage. - CSRF (Cross-Site Request Forgery): otra web hace que tu navegador envíe una petición autenticada sin que lo sepas, aprovechando el envío automático de cookies. Se combate con
SameSitey tokens sincronizadores (08-03). - Fijación de sesión: el atacante planta un identificador de sesión conocido antes del login y espera a que la víctima entre con él. Defensa: regenerar el identificador al iniciar sesión (08-03).
- Secuestro de sesión: robar una sesión ya válida (por XSS, red insegura o registros mal hechos). Defensa:
HttpOnly,Secure, caducidad corta, rotación. - Fuerza bruta: probar muchas contraseñas contra una cuenta. Defensa: hash lento y límite de intentos (08-02, 08-06).
- Relleno de credenciales (credential stuffing): probar pares correo/contraseña filtrados de otros servicios contra el nuestro. Defensa: límites, detección de anomalías, comprobación contra listas de contraseñas filtradas y MFA.
- Por qué no se implementa criptografía propia
La regla, sin matices: no diseñes criptografía y no implementes primitivas criptográficas. Usa bibliotecas revisadas por la comunidad durante años.
Las razones no son de humildad, son técnicas:
- Un algoritmo puede ser correcto y aun así filtrar información por el tiempo de ejecución, por el consumo de memoria o por los mensajes de error.
- Los detalles que deciden la seguridad son invisibles: rellenos, vectores de inicialización, modos de operación, generación de aleatoriedad.
- La criptografía rota no falla de forma visible: sigue devolviendo resultados perfectos hasta el día que alguien la rompe.
Lo mismo vale para los esquemas de token caseros. La tentación clásica es guardar en la cookie algo como usuario=lucia|rol=administrador|caduca=... y firmarlo «con un hash del secreto y los datos concatenados». Ese diseño concreto es vulnerable a extensión de longitud, a confusión de separadores y a comparaciones no constantes. JWT existe precisamente porque este problema ya está resuelto, con especificación pública y bibliotecas auditadas.
Lo que sí haremos con node:crypto es lo que está pensado para usarse: generar bytes aleatorios (randomBytes), hashear tokens de un solo uso (createHash) y comparar en tiempo constante (timingSafeEqual, que ya vimos en el módulo 3 con los Buffers, y que aquí por fin cobra sentido).
- El diseño elegido para Escena Viva
Estas son las decisiones del módulo, escritas ahora para que las cinco lecciones siguientes sean su implementación:
| Decisión | Elección | Motivo |
|---|---|---|
| Almacén de credenciales | Usuario de Mongoose (M7) con hashContrasena y select: false |
El modelo ya existe; solo le faltaba la contraseña |
| Hash de contraseñas | bcrypt con factor de coste medido | Estándar maduro, sin dependencias nativas problemáticas |
| Sesión de servidor | express-session + Passport local, enseñado y montado |
Es la base conceptual y la mejor opción para muchas apps |
| Autenticación oficial de la API | JWT de acceso (15 min) + refresco en cookie httpOnly |
Front-end estático y futuro cliente móvil |
| Autorización | RBAC con los roles ya modelados + propiedad del recurso | Tres roles claros; la propiedad cubre lo que RBAC no |
| Política de acceso | Centralizada en src/autorizacion/politica.js |
Se prueba sola (M9) y no se dispersa en if |
Y el mapa de rutas resultante:
| Zona | Rutas | Quién entra |
|---|---|---|
| Pública | GET /api/eventos, GET /api/eventos/:id, GET /api/sesiones |
Cualquiera |
| Autenticación | POST /auth/registro, /auth/login, /auth/refrescar, /auth/logout |
Cualquiera (con límites estrictos) |
| Autenticada | POST /api/compras, GET /api/pedidos, GET /api/pedidos/:id |
Asistente (solo lo suyo) |
| Organizador | POST /api/eventos, PATCH /api/eventos/:id/publicar, GET /api/salas/:sala/ventas |
Organizador de esa sala |
| Administración | PATCH /api/usuarios/:id/rol, PATCH /api/entradas/:codigo/anular |
Administrador |
El flujo que implementaremos entre 08-02 y 08-04:
sequenceDiagram
participant C as Cliente (front-end)
participant A as API Escena Viva
participant D as Base de datos
C->>A: POST /auth/registro {email, contrasena, nombre}
A->>A: Validar con zod y normalizar el correo
A->>A: bcrypt.hash(contrasena, coste)
A->>D: Crear Usuario {email, hashContrasena, rol: 'asistente'}
A-->>C: 201 {id, email, nombre, rol} (sin el hash)
C->>A: POST /auth/login {email, contrasena}
A->>D: Buscar usuario por email (+select hashContrasena)
A->>A: bcrypt.compare (tiempo constante)
alt Credenciales correctas
A->>D: Guardar hash del token de refresco
A-->>C: 200 {tokenAcceso} + Set-Cookie: refresco (HttpOnly)
else Credenciales incorrectas
A-->>C: 401 mensaje genérico e idéntico
end
C->>A: GET /api/pedidos (Authorization: Bearer tokenAcceso)
A->>A: Verificar firma, exp, iss, aud
A->>D: Consultar pedidos filtrando por req.usuario.id
A-->>C: 200 [pedidos propios]
Fíjate en el último paso: la consulta filtra por el usuario autenticado, no compara después. Es la diferencia entre una API segura y una con IDOR.
- Datos personales y RGPD
Autenticar implica guardar datos personales, y eso tiene consecuencias legales además de técnicas.
- Minimización: guarda solo lo imprescindible. Para vender entradas bastan correo, nombre y rol. Ni DNI, ni teléfono, ni fecha de nacimiento «por si acaso».
- Finalidad: los datos recogidos para vender entradas no se usan para marketing sin consentimiento separado.
- Derecho de supresión: debe existir una vía real para borrar una cuenta. Ojo: las entradas vendidas suelen tener obligaciones contables, así que lo habitual es anonimizar el usuario y conservar el pedido.
- Contraseñas: un hash bcrypt es un dato personal en la práctica. Trátalo como tal.
- Registros: los logs con correos e IPs también son datos personales; necesitan política de retención.
- Notificación de brechas: si se filtran credenciales hay obligación de notificar en plazo. Tener el incidente previsto por escrito, antes de que ocurra, es parte del trabajo.
En Escena Viva usamos correos ficticios con dominio .test precisamente para no manejar datos reales durante el curso.
Errores Comunes y Consejos
- Creer que 401 significa «sin permiso». Significa «no autenticado» (el nombre de la especificación es desafortunado). Sin permiso es 403. Confundirlos hace que los clientes redirijan al login a un usuario que ya ha entrado.
- Guardar el rol en el cliente y confiar en él. Ocultar un botón en el front-end no es autorización: la petición se puede enviar igual con
curl. - Usar
localStoragepara el token porque «es más cómodo». Un solo XSS lo convierte en un robo de identidad silencioso. Lo veremos en detalle en 08-04. - Añadir
SameSite=Nonepara «arreglar» un problema de CORS. Suele ser el síntoma de un diseño de dominios mal pensado, y abre la puerta a CSRF. - Pensar que TLS resuelve la autenticación. HTTPS protege el transporte, no dice quién eres ni qué puedes hacer.
- Consejo: escribe el modelo de amenazas antes del código, aunque sean diez líneas en un fichero. Es lo que evita implementar defensas para ataques que no te afectan y olvidar el que sí.
- Consejo: distingue siempre credencial de identificador. Si un dato basta para actuar en nombre de alguien, es una credencial y merece protección de credencial.
Ejercicios
Ejercicio 1: clasificar peticiones
Para cada una de estas situaciones de Escena Viva, indica si el fallo es de autenticación o de autorización, y qué código HTTP corresponde:
- Alguien llama a
POST /api/comprassin ninguna credencial. - Marc, con sesión válida, pide
GET /api/pedidos/ped-042, que es de Lucía. - El organizador de la Sala Bóveda intenta publicar
evt-001, del Teatro Almendra. - Se envía un token de acceso caducado.
- Un asistente intenta
PATCH /api/usuarios/:id/rol.
Ejercicio 2: elegir estrategia
Justifica en dos o tres frases qué estrategia de la tabla de la sección 4 elegirías para:
- Un panel interno de administración de Escena Viva, servido por el propio servidor con plantillas HTML.
- Una futura app móvil de Escena Viva para validar entradas en la puerta del Auditorio Ribera.
- Un servicio de facturación que llama cada noche a
GET /api/salas/:sala/ventas.
Ejercicio 3: cabecera Set-Cookie
Escribe la cabecera Set-Cookie completa para el token de refresco de Escena Viva sabiendo que: la API vive en api.escenaviva.test, el token solo debe enviarse a /auth/refrescar, dura 30 días, no debe ser legible por JavaScript, solo viaja por HTTPS y no queremos que se envíe desde otros sitios. Explica cada atributo.
Soluciones
Ejercicio 1
| Caso | Tipo | Código |
|---|---|---|
| 1 | Autenticación (no hay identidad) | 401 |
| 2 | Autorización (identidad válida, recurso ajeno) | 403 o 404 para no revelar existencia |
| 3 | Autorización (rol correcto, propiedad incorrecta) | 403 |
| 4 | Autenticación (credencial no válida ya) | 401, indicando que ha caducado para que el cliente refresque |
| 5 | Autorización (rol insuficiente) | 403 |
El caso 3 es especialmente instructivo: el rol organizador es correcto, y aun así la operación debe denegarse. RBAC solo no basta; hace falta comprobar la propiedad del recurso (08-05).
Ejercicio 2
- Sesiones de servidor con cookie. Es un único origen, el servidor renderiza HTML, el navegador gestiona la cookie sin código propio y la revocación es inmediata: si despides a un administrador, borras su sesión y queda fuera al instante.
- JWT de acceso corto + token de refresco guardado en el almacén seguro del sistema operativo. Las cookies no encajan fuera del navegador y el validador de entradas necesita funcionar con conectividad intermitente; un token firmado con caducidad corta se verifica sin consultar la base en cada lectura.
- Clave de API (o credenciales de cliente OAuth 2.0) con ámbito de solo lectura sobre ventas, rotable y revocable de forma independiente. No es una persona: no debe tener contraseña ni sesión.
Ejercicio 3
Set-Cookie: refresco=<token>; HttpOnly; Secure; SameSite=Strict; Path=/auth/refrescar; Max-Age=2592000HttpOnly:document.cookieno la ve, así que un XSS no puede exfiltrarla.Secure: solo por HTTPS; nunca en claro por la red.SameSite=Strict: no se envía en peticiones originadas por otros sitios, lo que anula el CSRF sobre el endpoint de refresco.Path=/auth/refrescar: no se adjunta a las llamadas normales de la API, reduciendo su exposición en logs y proxies.Max-Age=2592000: 30 días en segundos; caducidad explícita en vez de cookie de sesión.- Sin
Domain: la cookie queda ligada al host exactoapi.escenaviva.test, sin propagarse a subdominios.
Conclusión
Ya tenemos el mapa. Autenticar es demostrar quién eres; autorizar es decidir qué puedes hacer; confundirlas es la causa de los agujeros más caros. HTTP no tiene estado, así que cada petición debe llevar una prueba de identidad, y las estrategias para lograrlo —básica, sesiones, JWT, claves de API, OAuth— tienen cada una su terreno. Las cookies, con sus atributos HttpOnly, Secure y SameSite, son la infraestructura sobre la que se apoya casi todo, y cada atributo neutraliza un ataque concreto. Conocemos el modelo de amenazas de Escena Viva, sabemos que no vamos a inventar criptografía y tenemos el diseño escrito: sesiones para entender, JWT con refresco en cookie para producir, RBAC más propiedad del recurso para autorizar.
Falta lo primero de todo: que exista una contraseña que verificar. El modelo Usuario lleva desde la lección 07-02 con su campo rol y sin ningún campo de contraseña, a propósito. En la siguiente lección, Registro de Usuarios y Hash de Contraseñas, llenamos ese hueco: por qué jamás se guarda una contraseña en claro ni con SHA-256, qué hace realmente bcrypt, cómo se elige su factor de coste, cómo se escribe un POST /auth/registro que no filtre qué correos existen, y cómo se hacen bien los tokens de verificación y de recuperación, que es donde más proyectos se rompen.
Curso de Node.js: De Principiante a Avanzado
Módulo 1: Introducción a Node.js
- ¿Qué es Node.js?
- Instalación y Configuración del Entorno
- Tu Primer Programa en Node.js
- El REPL de Node.js
- JavaScript Moderno para Node.js
- El Proyecto del Curso: la Plataforma Escena Viva
Módulo 2: Conceptos Básicos
- Arquitectura de Node.js
- El Bucle de Eventos (Event Loop)
- Callbacks y Programación Asíncrona
- Promesas y async/await
- Eventos y EventEmitter
- Módulos CommonJS y require()
- Módulos ES e Interoperabilidad
Módulo 3: Sistema de Archivos y E/S
- Lectura y Escritura de Archivos
- El Módulo fs a Fondo
- Rutas Multiplataforma con el Módulo path
- Trabajando con Streams
- Streams de Transformación y pipeline
- Buffers y Datos Binarios
Módulo 4: HTTP y Servidores Web
- Creando un Servidor HTTP Simple
- Manejo de Solicitudes y Respuestas
- Enrutamiento Manual
- Sirviendo Archivos Estáticos
- Recibiendo Datos: Cuerpos de Petición y JSON
- Consumiendo APIs Externas desde Node.js
Módulo 5: NPM y Gestión de Paquetes
- Introducción a NPM y package.json
- Instalación y Uso de Paquetes
- Versionado Semántico y package-lock
- Scripts de npm y Automatización del Proyecto
- Creación y Publicación de Paquetes
- Seguridad y Mantenimiento de Dependencias
Módulo 6: Framework Express.js
- Introducción a Express.js
- Configuración de una Aplicación Express
- Enrutamiento en Express
- Middleware
- Middleware de Terceros Esenciales
- Validación de Datos de Entrada
- Manejo de Errores
Módulo 7: Bases de Datos y ORMs
- Introducción a las Bases de Datos
- Usando MongoDB con Mongoose
- Operaciones CRUD
- Relaciones, Poblado y Consultas Avanzadas
- Usando Bases de Datos SQL con Sequelize
- Migraciones, Transacciones y Datos de Prueba
Módulo 8: Autenticación y Autorización
- Introducción a la Autenticación
- Registro de Usuarios y Hash de Contraseñas
- Sesiones y Cookies con Passport.js
- Autenticación con JWT
- Control de Acceso Basado en Roles
- Buenas Prácticas de Seguridad en APIs
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con Mocha y Chai
- Dobles de Prueba con Sinon
- Pruebas de Integración
- Cobertura y Automatización de las Pruebas
- Depuración de Aplicaciones Node.js
Módulo 10: Temas Avanzados
- El Módulo Cluster
- Hilos de Trabajo (Worker Threads)
- Caché y Colas de Trabajo con Redis
- Optimización del Rendimiento
- Construcción de APIs RESTful
- GraphQL con Node.js
Módulo 11: Despliegue y DevOps
- Configuración y Variables de Entorno
- Registro y Monitorización en Producción
- Usando PM2 para la Gestión de Procesos
- Empaquetado con Docker
- Desplegando en Heroku y Otras PaaS
- Integración y Despliegue Continuos
