Cómo crear un endpoint seguro con Fastify

Clase 24 de 28Curso para Certificacion de Node.js con OpenJS Foundation 2023

Resumen

Aprende a resolver el dominio Security (30 %) de la certificación JS en SD con un servidor en Fastify, un endpoint de autenticación y control de rate limit. Verás cómo manejar status codes 200, 401 y 429, configurar package.json y usar top‑level await con archivo .mjs.

¿Qué evalúa el dominio security en JS en SD?

Este dominio valida prácticas de seguridad en API Rest con Node. Se compone de dos tareas (task 1.1 y 1.2) y exige escribir cantidad significativa de código. La clave: especializarse en un framework favorito para resolver más rápido y con calidad.

¿Qué peso tiene y qué exige?

  • Pesa 30 % de la prueba total.
  • Enfocado en riesgos comunes en API Rest y su mitigación.
  • Ejercicios extensos: escribir código real y probado.

¿Qué recursos se mencionan para prepararte?

  • Artículo de Snyk con prácticas comunes de seguridad.
  • Repositorio en GitHub: awesomesecurity-nodejs.
  • Un cheat sheet para consultas rápidas.

Habilidades puestas en juego: conocer riesgos de API Rest, dominar plugins de seguridad del framework, manejar variables de entorno, trabajar con .gitignore, instalar dependencias con npm install y probar con Postman o Insomnia.

¿Cómo construir el endpoint /login con Fastify y validar credenciales?

El objetivo: un web server que escuche en la variable de entorno port (fallback 3000), un único endpoint /login que acepte método POST con JSON username y password, y devuelva el status code correcto según la función login.

¿Qué reglas de negocio aplica el login?

  • login(username, password) retorna true si usuario es Node y contraseña developer.
  • Si es válido: 200.
  • Si es inválido: 401.
  • Sin cuerpo adicional: solo el status code (puedes enviar {} vacío).

¿Cómo se implementa con Fastify?

// answer.mjs
import Fastify from 'fastify'

// servidor con logger
const fastify = Fastify({ logger: true })

// función dada por el enunciado
function login(user, pwd) {
  return user === 'Node' && pwd === 'developer'
}

// endpoint POST /login con JSON { username, password }
fastify.post('/login', async (request, reply) => {
  const { username, password } = request.body || {}
  const validUser = login(username, password)

  if (!validUser) {
    return reply.code(401).send({})
  }
  return reply.code(200).send({})
})

// escucha en la variable de entorno `port` o 3000
const PORT = Number(process.env.port) || 3000
await fastify.listen({ port: PORT })

Consejo práctico: consulta la documentación de tu framework mientras implementas; ahorra tiempo y evita errores.

¿Cómo aplicar rate limit y preparar la ejecución con .mjs?

Se requiere bloquear por IP cuando un cliente haga más de 3 requests en 15 segundos a /login y responder con 429. Para ello se usa el plugin de rate limit del ecosistema de Fastify y un error handler que establezca el status code.

¿Cómo configurar el plugin y el error handler?

import rateLimit from '@fastify/rate-limit'

await fastify.register(rateLimit, {
  max: 3,
  timeWindow: 15_000,
  errorResponseBuilder: () => ({
    statusCode: 429
  })
})

Notas importantes: - Se usa top‑level await: renombra el archivo a .mjs para ejecutarlo como módulo y habilitarlo. - El plugin limita por IP y cumple con el bloqueo solicitado.

¿Cómo iniciar el servidor desde package.json?

{
  "name": "security-task",
  "type": "module",
  "scripts": {
    "start": "node answer.mjs"
  }
}
  • Ejecuta: npm start.
  • Prueba con Postman o Insomnia: /login vía POST, cuerpo JSON con username y password.
  • Verifica los flujos: 200 válido, 401 inválido, 429 al cuarto request en 15 s.

¿Tienes otra estrategia de seguridad con tu framework favorito o dudas sobre el rate limit? Cuéntalo en los comentarios y enriquezcamos juntos la solución.

      Cómo crear un endpoint seguro con Fastify