Sugerencias
← TIL
~2 min de lectura
#astro#edge#middleware#auth#performance

Auth en el edge con Astro 6: JWT sin round-trip al servidor

Un cliente llegó con 300ms de TTFB en /dashboard. Diagnóstico: cada request disparaba un SELECT a la DB para verificar la sesión.

src/middleware.ts en Astro 6 se despliega en el edge e intercepta todo request antes del origen. JWT verification es CPU-only; verificás contra el secreto que ya está en las variables de entorno del runtime, sin tocar la red:

src/middleware.ts
import { defineMiddleware } from "astro:middleware";
import { verifyJWT } from "./lib/auth";

export const onRequest = defineMiddleware(async (context, next) => {
  const token = context.cookies.get("session")?.value;

  if (!token && context.url.pathname.startsWith("/dashboard")) {
    return context.redirect("/login");
  }

  if (token) {
    const payload = verifyJWT(token); // síncrona, sin await
    if (!payload) return context.redirect("/login");
    context.locals.user = payload;
  }

  return next();
});

verifyJWT no hace llamadas de red. Si usás jsonwebtoken, verify() sin callback es síncrona. Si usás jose, jwtVerify() retorna una Promise; podés await-earla igual porque es pura CPU, sin I/O. En ambos casos el resultado llega en ~1ms.

Para que context.locals.user tenga tipos correctos en tus páginas, agregá esto a src/env.d.ts:

src/env.d.ts
declare namespace App {
  interface Locals {
    user?: { id: string; email: string; role: string };
  }
}

Cuándo el edge no te ayuda

Si usás session tokens opacos (un UUID que mapea a un registro en DB), el middleware va a verse así:

src/middleware.ts: el anti-patrón
// Esto te da los mismos 200ms, pero ahora en el edge
const sessionId = context.cookies.get("session")?.value;
const user = await db.findBySession(sessionId); // 80-200ms de DB round-trip

Para mantener la ventaja, el lookup tiene que ir a un KV store en el mismo runtime. En Astro 6 con el adapter de Cloudflare, el acceso a bindings usa el módulo nativo:

Con Cloudflare Workers KV
import { env } from "cloudflare:workers";

const sessionId = context.cookies.get("session")?.value;
const user = await env.KV.get(`session:${sessionId}`);
// 2-5ms en lugar de 80-200ms

En Vercel Edge el patrón es distinto (Edge Config SDK). La lógica es la misma; cambia la API de acceso al store.

La diferencia no es de velocidad de red sino de tipo de dependencia. JWT: el secreto ya está en las vars de entorno, sin llamada de red. Session ID opaco: siempre necesita buscar en algún lugar externo. Si ese lugar es una DB en Virginia y vos estás en Asunción, el edge no te salva.

Enlace copiado al portapapeles