Implementar Rate Limiting en Astro con Cloudflare Workers
LaunchFast Logo LaunchFast

Implementar Rate Limiting en Astro con Cloudflare Workers

Rishi Raj Jain
Implementar Rate Limiting en Astro con Cloudflare Workers

El rate limiting es esencial para proteger tus APIs y páginas contra abusos, ataques de fuerza bruta y uso excesivo. Cloudflare Workers proporciona un binding de Rate Limiting integrado que facilita implementar rate limiting en el edge.

Kits de inicio de alta calidad con flujo de autenticación integrada (Auth.js), carga de objetos (AWS, Clouflare R2, Firebase Storage, Supabase Storage), pagos integrados (Stripe, LemonSqueezy), flujo de verificación de correo electrónico (Resend, Postmark, Sendgrid) y mucho más . Compatible con cualquier base de datos (Redis, Postgres, MongoDB, SQLite, Firestore).

En esta guía, aprenderás cómo implementar rate limiting en Astro usando la API de Rate Limiting de Cloudflare, tanto globalmente a través de middleware como a nivel de endpoint.

Requisitos Previos

Crear una nueva aplicación Astro

Comencemos creando un nuevo proyecto Astro. Ejecuta el siguiente comando:

Terminal window
npm create astro@latest my-ratelimit-astro-app

Cuando se te pregunte, elige:

  • Use minimal (empty) template cuando se te pregunte cómo comenzar el nuevo proyecto.
  • Yes cuando se te pregunte si instalar dependencias.
  • Yes cuando se te pregunte si inicializar un repositorio git.

Una vez hecho, muévete al directorio del proyecto:

Terminal window
cd my-ratelimit-astro-app
npm install wrangler
npm run dev

La aplicación debería estar ejecutándose en localhost:4321.

Integrar el adaptador Cloudflare en tu proyecto Astro

Para desplegar tu proyecto Astro en Cloudflare Workers y usar Cloudflare KV, necesitas instalar el adaptador de Cloudflare. Ejecuta el siguiente comando:

Terminal window
npx astro add cloudflare

Cuando se te pregunte, elige Yes para cada prompt.

Configurar el binding de Rate Limiting

Agrega el binding de rate limiting a tu wrangler.jsonc:

wrangler.jsonc
{
// ...
"ratelimits": [
{
"namespace_id": "1001",
"name": "MY_RATE_LIMITER",
"simple": {
"limit": 100,
"period": 60
}
}
]
}

Esta configuración:

  • Crea un rate limiter llamado MY_RATE_LIMITER
  • Permite 100 solicitudes por 60 segundos por clave única
  • Usa namespace_id para aislar los contadores de rate limit

Actualiza tu src/env.d.ts para agregar definiciones de TypeScript:

/// <reference types="astro/client" />
type RateLimiter = {
limit: (options: { key: string }) => Promise<{ success: boolean }>
}
type ENV = {
MY_RATE_LIMITER: RateLimiter
}
type Runtime = import('@astrojs/cloudflare').Runtime<ENV>
declare namespace App {
interface Locals extends Runtime {}
}

Rate Limiting en Astro Middleware

Para aplicar rate limiting globalmente (o a rutas específicas), crea un archivo middleware en src/middleware.ts:

src/middleware.ts
import { defineMiddleware } from 'astro:middleware'
// Rutas con rate limiting
const RATE_LIMITED_ROUTES = ['/']
export const onRequest = defineMiddleware(async (context, next) => {
const { url, request, locals } = context
const pathname = url.pathname
// Verificar si la ruta debe tener rate limiting
const shouldRateLimit = RATE_LIMITED_ROUTES.some((route) =>
pathname === (route)
)
if (!shouldRateLimit) {
return next()
}
// Omitir si el rate limiter no está disponible (desarrollo local)
const rateLimiter = locals.runtime?.env?.MY_RATE_LIMITER
if (!rateLimiter) {
console.log('[Rate Limit] Binding no disponible, omitiendo')
return next()
}
// Usar IP del cliente como clave de rate limit
const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown'
try {
const { success } = await rateLimiter.limit({ key: clientIP })
if (!success) {
return new Response(
JSON.stringify({
error: 'Demasiadas Solicitudes',
message: 'Límite de velocidad excedido. Por favor, intenta de nuevo más tarde.',
}),
{
status: 429,
headers: {
'Content-Type': 'application/json',
'Retry-After': '60',
},
}
)
}
} catch (error) {
console.error('[Rate Limit] Error:', error)
// En caso de error, permitir la solicitud (fail open)
}
return next()
})
Implementar Rate Limiting en Astro Middleware con Cloudflare Workers

Este middleware:

  1. Verifica si la ruta actual debe tener rate limiting
  2. Usa la dirección IP del cliente como clave de rate limit
  3. Retorna una respuesta 429 Too Many Requests cuando se excede el límite

Rate Limiting en un Endpoint de API

Para un control más granular, aplica rate limiting directamente en tus endpoints de API. Crea src/pages/api/data.ts:

src/pages/api/data.ts
import type { APIContext } from 'astro'
export async function GET({ request, locals }: APIContext) {
const rateLimiter = locals.runtime?.env?.MY_RATE_LIMITER
if (rateLimiter) {
const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown'
const { success } = await rateLimiter.limit({ key: clientIP })
if (!success) {
return new Response(
JSON.stringify({ error: 'Límite de velocidad excedido' }),
{
status: 429,
headers: { 'Content-Type': 'application/json' },
}
)
}
}
// Tu lógica del endpoint aquí
return new Response(
JSON.stringify({ message: 'Éxito', data: { timestamp: Date.now() } }),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
}
)
}
Implementar Rate Limiting en Astro Endpoint con Cloudflare Workers

Este endpoint:

  1. Usa la dirección IP del cliente como clave de rate limit
  2. Retorna una respuesta 429 Rate Limit Exceeded cuando se excede el límite

Claves de Rate Limit Personalizadas

Puedes usar diferentes claves para diferentes estrategias de rate limiting:

// Rate limit por ID de usuario (para rutas autenticadas)
const userId = locals.user?.id
const { success } = await rateLimiter.limit({ key: `user:${userId}` })
// Rate limit por combinación de IP + endpoint
const key = `${clientIP}:${url.pathname}`
const { success } = await rateLimiter.limit({ key })
// Rate limit por clave de API
const apiKey = request.headers.get('X-API-Key') || 'anonymous'
const { success } = await rateLimiter.limit({ key: `api:${apiKey}` })

Desplegar en Cloudflare Workers

Despliega tu aplicación Astro con rate limiting habilitado a producción:

Terminal window
# Construir el proyecto
npm run build
# Desplegar en Cloudflare Workers
npx wrangler deploy

Conclusión

Al implementar rate limiting con Cloudflare Workers en tu aplicación Astro, bloqueas efectivamente solicitudes abusivas - como ataques de fuerza bruta, uso excesivo de API e intentos de DDoS en el edge. Esto mejora tanto la seguridad como el rendimiento de tu aplicación al detener las amenazas antes de que lleguen a la lógica de tu aplicación.

Learn More Cómo Implementar Autorización Básica en Astro
Cómo Implementar Autorización Básica en Astro July 16, 2025
Soporte para Cloudflare D1 Database ahora disponible en LaunchFast Starter Kits
Soporte para Cloudflare D1 Database ahora disponible en LaunchFast Starter Kits July 3, 2025
Soporte para Mailgun Email ahora disponible en LaunchFast Starter Kits
Soporte para Mailgun Email ahora disponible en LaunchFast Starter Kits June 7, 2025