Quiz: Server Actions y seguridad

Quiz
10 min~4 min lectura

Quiz Interactivo

Pon a prueba tus conocimientos

Concepto clave

Las Server Actions en Next.js 15 son funciones que se ejecutan exclusivamente en el servidor, permitiendo manipular datos sin exponer APIs REST tradicionales. Piensa en ellas como "cajeros automáticos seguros": el usuario interactúa con una interfaz (el cajero), pero toda la lógica de transacciones ocurre dentro del sistema bancario protegido. Esto elimina la necesidad de crear endpoints manuales para operaciones como crear, actualizar o eliminar datos.

La seguridad es inherente porque el código nunca se envía al cliente. Sin embargo, debes protegerlas contra amenazas como CSRF (Cross-Site Request Forgery) o inyección de datos. Next.js incluye protecciones automáticas, pero como desarrollador debes validar entradas y gestionar permisos. Un error común es asumir que "porque es del servidor, ya es seguro", ignorando validaciones básicas.

Cómo funciona en la práctica

Para usar una Server Action, la defines en un archivo del servidor (ej: actions.ts) con 'use server' y la importas en un componente. Aquí un ejemplo paso a paso para un formulario de contacto:

  1. Crea app/actions/contact.ts:
    'use server'
    import { revalidatePath } from 'next/cache'
    export async function sendContact(formData: FormData) {
      const name = formData.get('name')?.toString()
      const email = formData.get('email')?.toString()
      // Validación: verifica que los campos no estén vacíos
      if (!name || !email) {
        return { error: 'Faltan campos requeridos' }
      }
      // Lógica de negocio: guardar en base de datos
      await db.contacts.create({ data: { name, email } })
      revalidatePath('/contacts')
      return { success: true }
    }
  2. Úsala en un componente React:
    'use client'
    import { sendContact } from '@/app/actions/contact'
    export default function ContactForm() {
      async function handleSubmit(formData: FormData) {
        const result = await sendContact(formData)
        if (result.error) alert(result.error)
      }
      return (
        <form action={handleSubmit}>
          <input name="name" />
          <input name="email" type="email" />
          <button type="submit">Enviar</button>
        </form>
      )
    }

Observa que sendContact solo se ejecuta en el servidor, protegiendo la lógica de base de datos.

Caso de estudio

Imagina una app de tareas (todo-list) donde los usuarios pueden agregar y completar tareas. Usando Server Actions, implementamos:

  • Acción: addTask(title: string) – valida el título, lo guarda en DB, y revalida la lista.
  • Seguridad: Verificamos que el usuario esté autenticado (usando cookies seguras) y que el título no exceda 100 caracteres para evitar ataques de desbordamiento.
  • Flujo: El cliente llama a addTask desde un formulario; el servidor procesa y devuelve el estado actualizado sin exponer la consulta SQL.
Dato importante: En producción, siempre combina Server Actions con middleware de autenticación y límites de tasa (rate limiting) para prevenir abusos.

Errores comunes

  1. No validar entradas: Asumir que los datos del formulario son seguros. Siempre valida tipos, longitudes y formatos en el servidor.
  2. Exponer errores detallados: Enviar mensajes de error del servidor al cliente puede filtrar información sensible. Usa respuestas genéricas como "Algo salió mal".
  3. Olvidar revalidación: No usar revalidatePath o revalidateTag después de mutar datos, dejando la caché desactualizada.
  4. Ignorar CSRF: Aunque Next.js lo maneja, deshabilitarlo sin razón compromete la seguridad. Verifica que las cookies estén configuradas correctamente.
  5. Manejo inadecuado de archivos: Si subes archivos, valida tipos y tamaños en el servidor para evitar ataques de inyección.

Checklist de dominio

  • Puedo crear una Server Action que valide datos de formulario y los guarde en una base de datos.
  • Sé cómo proteger acciones con autenticación (ej: usando cookies o tokens en middleware).
  • Entiendo cuándo usar revalidatePath para actualizar cachés después de mutaciones.
  • Reconozco y evito errores comunes como no validar entradas o exponer detalles de error.
  • Puedo integrar Server Actions en componentes cliente manteniendo la interactividad.
  • Sé cómo probar Server Actions en desarrollo usando herramientas como console.log en el servidor.
  • Comprendo la diferencia entre Server Actions y APIs tradicionales en términos de seguridad y flujo de datos.

Implementa una Server Action segura para actualizar perfil de usuario

En este ejercicio, crearás una Server Action que permita a usuarios actualizar su nombre en un perfil, con validaciones de seguridad. Sigue estos pasos:

  1. Crea un archivo app/actions/profile.ts y define una acción updateProfile con 'use server'.
  2. La acción debe aceptar un objeto con userId (string) y newName (string).
  3. Implementa validaciones: verifica que userId corresponda al usuario autenticado (simula con una constante por ahora) y que newName tenga entre 2 y 50 caracteres.
  4. Si las validaciones pasan, simula guardar en una base de datos (usa console.log) y devuelve un objeto con { success: true, message: 'Perfil actualizado' }.
  5. En caso de error, devuelve { success: false, error: 'Mensaje descriptivo' } sin detalles internos.
  6. Crea un componente cliente en app/profile/page.tsx que use un formulario para llamar a esta acción y muestre el resultado.
Pistas
  • Usa typeof y .length para validar el nombre en la Server Action.
  • Recuerda que las Server Actions deben manejar errores con try-catch para no crashear el servidor.
  • En el componente cliente, usa useState para manejar el estado de envío y respuesta.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.