Saltar al contenido

Lección 12 de 20 · Lectura y práctica

Integra autenticación con cookies y sesiones

Concepto claveLa autenticación con cookies y sesiones es el mecanismo más robusto para manejar usuarios en aplicaciones web full-stack. Imagina que una cookie es como una tarjeta de identificación que el servidor le da al.

Del concepto a la práctica

Taller de esta lección

Una cookie de sesión solo debe identificar; la información completa vive en el servidor. El flujo correcto es comprobar el identificador, buscar la sesión, verificar su expiración y colocar el usuario autenticado en el contexto de la solicitud. La autorización se evalúa después, sobre cada recurso.

Ejemplo resuelto

Considera la sesión {id: 's1', userId: 'u1', expiresAt: '2026-10-09T10:00:00Z'} y una petición el mismo2026-10-09 a las09:30 UTC. La sesión es válida y el servidor puede cargar a u1. A las 10:01, la misma cookie debe tratarse como expirada.

s1 es una etiqueta didáctica, no un token impredecible de sesión. El emisor real genera un identificador opaco aleatorio, rota al autenticar y guarda expiración/revocación en servidor. En hooks.server.js resuelve event.cookies.get("session") y escribe event.locals.user únicamente tras validar; cada acción vuelve a comprobar user y propiedad. Declara cookies.set con path:"/",httpOnly:true,sameSite:"lax" y secure:true en HTTPS; para localhost HTTP solo el desarrollo permite secure:false. Cerrar sesión revoca servidor y elimina cookie con el mismo path. Un layout load no se ejecuta necesariamente en cada navegación: no debe ser la única protección.

Pruébalo

  1. Lee la cookie sin aceptar su contenido como perfil.

  2. Busca la sesión en el almacenamiento del servidor.

  3. Compara expiresAt con la hora actual.

  4. Rechaza la solicitud si no hay sesión válida.

Comprueba tu resultado

Error frecuente: guardar el usuario completo o la contraseña en la cookie; corrígelo guardando solo un identificador opaco.

Ejercicio: evalúa la sesión a las 09:30 y 10:01. Resultado esperado: acceso permitido primero y rechazado después.

Capas de acceso, actualización, copias y respuesta a incidentes alrededor de un sistema.
CursaloMapa de práctica
La seguridad necesita varias capas

El control de acceso, las actualizaciones y las copias de seguridad cubren riesgos distintos. Una alerta necesita un procedimiento de respuesta para contener y recuperar el servicio. Varias capas reducen la exposición, pero ninguna garantiza seguridad absoluta.

Ver la infografía en tamaño completo ↗

Concepto clave

La autenticación con cookies y sesiones es el mecanismo más robusto para manejar usuarios en aplicaciones web full-stack. Imagina que una cookie es como una tarjeta de identificación que el servidor le da al navegador, y la sesión es el expediente completo del usuario guardado en el servidor. Cada vez que el navegador visita el sitio, muestra su tarjeta (cookie), y el servidor consulta el expediente (sesión) para verificar quién es.

En SvelteKit, este flujo se integra naturalmente con las Server Actions y el manejo de estado global. A diferencia de soluciones cliente-only como JWT en localStorage, las cookies son automáticamente enviadas con cada request, lo que permite autenticación segura tanto en el servidor como en el cliente. Esto es crucial para aplicaciones performantes, ya que evita llamadas API redundantes y permite renderizado optimizado.

Cómo funciona en la práctica

El proceso sigue estos pasos:

  1. El usuario envía credenciales mediante un formulario que ejecuta una Server Action.
  2. La Server Action valida las credenciales en la base de datos.
  3. Si son válidas, crea una sesión en el servidor (por ejemplo, en una tabla de sesiones) y genera una cookie segura con un ID único.
  4. La cookie se envía al navegador con headers HTTP, y el navegador la almacena automáticamente.
  5. En requests futuros, SvelteKit verifica la cookie en hooks como handle o load functions, recupera la sesión, y hace disponible el estado del usuario.

Este enfoque separa claramente la lógica: el servidor maneja la autenticación real, mientras el cliente solo necesita saber si el usuario está logueado o no, ideal para optimizar rendimiento.

Código en acción

Primero, configura una Server Action para login en src/routes/login/+page.server.js:

// Server Action para login
export const actions = {
  default: async ({ cookies, request }) => {
    const data = await request.formData();
    const email = data.get('email');
    const password = data.get('password');
    
    // Validar con base de datos (ejemplo con Prisma)
    const user = await prisma.user.findUnique({ where: { email } });
    if (!user || !(await verifyPassword(password, user.passwordHash))) {
      return { error: 'Credenciales inválidas' };
    }
    
    // Crear sesión en base de datos
    const session = await prisma.session.create({
      data: {
        userId: user.id,
        expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7) // 7 días
      }
    });
    
    // Configurar cookie segura
    cookies.set('session_id', session.id, {
      path: '/',
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'strict',
      maxAge: 60 * 60 * 24 * 7
    });
    
    return { success: true, redirect: '/dashboard' };
  }
};

Luego, en src/hooks.server.js, verifica la cookie en cada request:

// Hook para manejar autenticación global
export async function handle({ event, resolve }) {
  const sessionId = event.cookies.get('session_id');
  
  if (sessionId) {
    // Recuperar sesión y usuario
    const session = await prisma.session.findUnique({
      where: { id: sessionId },
      include: { user: true }
    });
    
    if (session && session.expiresAt > new Date()) {
      event.locals.user = session.user; // Estado disponible globalmente
      event.locals.session = session;
    } else {
      // Sesión expirada, limpiar cookie
      event.cookies.delete('session_id', { path: '/' });
    }
  }
  
  const response = await resolve(event);
  return response;
}

Errores comunes

  • No configurar cookies como httpOnly: Deja las cookies accesibles desde JavaScript, exponiéndolas a ataques XSS. Siempre usa httpOnly: true para cookies de sesión.
  • Olvidar limpiar sesiones expiradas: Acumulan basura en la base de datos. Programa tareas periódicas o usa TTL en tu base de datos para eliminarlas automáticamente.
  • No validar el origen de la cookie: Ataques CSRF pueden suplantar sesiones. Usa tokens CSRF o asegura que sameSite esté en 'strict' o 'lax'.
  • Almacenar datos sensibles en la cookie: La cookie solo debe contener un ID de sesión, nunca información del usuario. Todo lo demás va en el servidor.
  • Ignorar el manejo de estado global: Sin integrar event.locals con stores de Svelte, el cliente no sabe el estado de autenticación. Usa un store derivado para sincronizarlo.

Checklist de dominio

  • Implementé una Server Action que valida credenciales y crea una sesión en base de datos.
  • Configuré cookies con flags de seguridad: httpOnly, secure, sameSite.
  • Integré un hook en hooks.server.js que verifica la cookie y popula event.locals.
  • Creé un store de Svelte que refleja el estado de autenticación desde event.locals.
  • Implementé logout que elimina la sesión de la base de datos y borra la cookie.
  • Protegí rutas sensibles verificando event.locals.user en load functions.
  • Probé el flujo completo en diferentes navegadores y dispositivos.

Implementa autenticación completa con cookies y sesiones en una app SvelteKit

En este ejercicio, construirás un sistema de autenticación desde cero en una aplicación SvelteKit existente. Sigue estos pasos:

  1. Crea una tabla de sesiones en tu base de datos (si usas Prisma, añade un modelo Session con id, userId, expiresAt).
  2. En src/routes/login/+page.svelte, crea un formulario con campos email y password que use una Server Action.
  3. Implementa la Server Action en +page.server.js que:
    • Valide las credenciales contra la tabla de usuarios.
    • Cree una nueva sesión en la tabla de sesiones.
    • Establezca una cookie segura con el sessionId.
  4. Modifica src/hooks.server.js para que en cada request:
    • Lea la cookie 'session_id'.
    • Busque la sesión correspondiente en la base de datos.
    • Si es válida, asigne el usuario a event.locals.user.
    • Si no, limpie la cookie.
  5. Crea un store en src/stores/auth.js que exponga el estado del usuario, sincronizado con event.locals.
  6. Implementa una ruta /dashboard que solo sea accesible para usuarios autenticados, mostrando su email.
  7. Añade un botón de logout que ejecute una Server Action para eliminar la sesión y borrar la cookie.

Entrega: Código funcional que permita login, mantenga sesión entre recargas, y restrinja acceso a rutas protegidas.

Pistas
  • Usa cookies.set con opciones de seguridad: httpOnly, secure, sameSite.
  • En el hook, verifica que la sesión no haya expirado comparando expiresAt con la fecha actual.
  • Para el store, considera usar writable y actualizarlo en una load function que lea de event.locals.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con SvelteKit Full-Stack: Construye Aplicaciones Web Performantes con Server Actions

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.