
Al construir aplicaciones web, hay momentos en los que necesitas proteger tus rutas antes de lanzar a producción. Ya sea que estés trabajando en un proyecto de cliente que necesita estar oculto del público o quieres agregar una capa de autenticación simple a tu entorno de desarrollo, la autorización básica es una solución rápida y efectiva.
En esta guía, te mostraremos cómo implementar autenticación básica en tu aplicación Astro usando middleware. Este enfoque es perfecto para protección temporal durante las fases de desarrollo o staging.
Tabla de Contenidos
¿Qué es la Autenticación Básica?
La autenticación básica es un esquema de autenticación simple integrado en el protocolo HTTP. Funciona de la siguiente manera:
- Solicitud del Cliente: El navegador envía una solicitud a una ruta protegida
- Desafío del Servidor: El servidor responde con un estado
401 Unauthorized
y un encabezadoWWW-Authenticate
- Prompt del Navegador: El navegador muestra un diálogo de inicio de sesión al usuario
- Credenciales: El usuario ingresa nombre de usuario/contraseña, que se codifica y envía con solicitudes posteriores
- Validación: El servidor valida las credenciales y permite o deniega el acceso
Implementación Paso a Paso
Paso 1: Crear una nueva aplicación Astro
Comencemos creando un nuevo proyecto Astro. Ejecuta el siguiente comando:
npm create astro@latest my-app
npm create astro
es la forma recomendada de crear rápidamente un proyecto Astro.
Cuando se te pregunte, elige:
Empty
cuando se te pregunte cómo comenzar el nuevo proyecto.Yes
cuando se te pregunte si planeas escribir TypeScript.Strict
cuando se te pregunte qué tan estricto debe ser TypeScript.Yes
cuando se te pregunte si instalar dependencias.Yes
cuando se te pregunte si inicializar un repositorio git.
Una vez que esté hecho, puedes moverte al directorio del proyecto y iniciar la aplicación:
cd my-appnpm run dev
La aplicación debería estar ejecutándose en localhost:4321.
Paso 2: Integrar el adaptador Node.js en tu proyecto Astro
Para habilitar el renderizado del lado del servidor en tu proyecto Astro a través del adaptador Node.js. Ejecuta el siguiente comando:
npx astro add node
Cuando se te pregunte, elige lo siguiente:
Yes
cuando se te pregunte si instalar las dependencias de Node.js.Yes
cuando se te pregunte si hacer cambios al archivo de configuración de Astro.
Esto instalará las dependencias necesarias y actualizará tu archivo astro.config.mjs
.
Paso 3: Crear un Archivo Middleware
Crea un nuevo archivo llamado middleware.ts
en tu directorio src/
con el siguiente código:
import { defineMiddleware } from 'astro:middleware'
// Define rutas protegidas que requieren "autenticación básica"// (solo para poner las páginas detrás de una autenticación básica antes de lanzar tu aplicación al mundo)const PROTECTED_ROUTES = [ // '/', // '/signin']
// Credenciales básicas (en producción, usa variables de entorno)const VALID_CREDENTIALS = { username: 'admin', password: 'password123',}
export const onRequest = defineMiddleware(async (context, next) => { const { url, request } = context const pathname = new URL(url).pathname
// Verifica si la ruta actual está protegida const isProtectedRoute = PROTECTED_ROUTES.some((route) => (route === '/' ? pathname === route : pathname.startsWith(route)) )
// Para rutas protegidas, verifica la autenticación if (isProtectedRoute) { const authHeader = request.headers.get('authorization')
if (!authHeader || !authHeader.startsWith('Basic ')) { // Retorna 401 Unauthorized con encabezado WWW-Authenticate return new Response('Autenticación requerida', { status: 401, headers: { 'WWW-Authenticate': 'Basic realm="Área Segura"', 'Content-Type': 'text/plain', }, }) }
// Extrae y decodifica las credenciales const encodedCredentials = authHeader.substring(6) const decodedCredentials = atob(encodedCredentials) const [username, password] = decodedCredentials.split(':')
// Valida las credenciales if (username !== VALID_CREDENTIALS.username || password !== VALID_CREDENTIALS.password) { return new Response('Credenciales inválidas', { status: 401, headers: { 'WWW-Authenticate': 'Basic realm="Área Segura"', 'Content-Type': 'text/plain', }, }) } }
// Continúa al siguiente middleware/manejador de ruta return next()})
Paso 4: Configurar Rutas Protegidas
En el archivo middleware, puedes especificar qué rutas deben estar protegidas descomentando o agregando rutas al array PROTECTED_ROUTES
:
const PROTECTED_ROUTES = [ '/', // Protege la página de inicio '/admin', // Protege todas las rutas que comiencen con /admin '/dashboard', // Protege todas las rutas que comiencen con /dashboard '/api', // Protege todas las rutas de API]
Paso 5: Configurar Variables de Entorno (Recomendado)
Para uso en producción, es mejor usar variables de entorno en lugar de credenciales codificadas. Crea un archivo .env
:
BASIC_AUTH_USERNAME=adminBASIC_AUTH_PASSWORD=tu-contraseña-segura
Luego actualiza el middleware para usar estas variables de entorno:
const VALID_CREDENTIALS = { username: import.meta.env.BASIC_AUTH_USERNAME || 'admin', password: import.meta.env.BASIC_AUTH_PASSWORD || 'password123',}
Cómo Funciona
1. Lógica de Protección de Rutas
El middleware verifica si la ruta actual está en el array PROTECTED_ROUTES
:
const isProtectedRoute = PROTECTED_ROUTES.some((route) => (route === '/' ? pathname === route : pathname.startsWith(route)))
Esto permite un emparejamiento flexible de rutas:
- Coincidencias exactas:
'/'
coincide solo con la página de inicio - Coincidencias de prefijo:
'/admin'
coincide con/admin
,/admin/users
,/admin/settings
, etc.
2. Flujo de Autenticación
Cuando un usuario visita una ruta protegida:
- Sin Encabezado de Auth: Si no hay encabezado
Authorization
presente, el servidor retorna una respuesta401
con un encabezadoWWW-Authenticate
- Prompt del Navegador: El navegador muestra un diálogo de inicio de sesión
- Credenciales Enviadas: El usuario ingresa credenciales, el navegador las envía codificadas en base64
- Validación: El servidor decodifica y valida las credenciales
- Acceso Concedido/Denegado: Si son válidas, la solicitud continúa; si son inválidas, se retorna otro
401
Conclusión
La autenticación básica en Astro es una forma directa de proteger tus rutas durante el desarrollo o staging. Si bien no es adecuada para la autenticación de usuarios en producción, es perfecta para:
- Protección de Desarrollo: Ocultar características en progreso
- Demos de Clientes: Proteger proyectos de clientes antes del lanzamiento
- Entornos de Staging: Asegurar sitios de staging
- Áreas de Administración: Protección rápida para interfaces de administración
El enfoque de middleware que hemos implementado es limpio, eficiente y fácil de personalizar para tus necesidades específicas. Recuerda usar variables de entorno para las credenciales y considera soluciones de autenticación más robustas para aplicaciones en producción.