Astro Middleware: Authentication และ Request Processing

#astro13 เม.ย. 2569

Middleware ใน Astro คืออะไร

Middleware ช่วยให้ intercept request และ response ก่อนที่จะถึง page หรือ API endpoint เหมาะสำหรับ authentication, logging, i18n

สร้าง Middleware

// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';

export const onRequest = defineMiddleware(async (context, next) => {
  console.log('Request:', context.url.pathname);
  const response = await next();
  console.log('Response:', response.status);
  return response;
});

Authentication Middleware

import { defineMiddleware } from 'astro:middleware';

const PROTECTED_ROUTES = ['/dashboard', '/admin', '/profile'];

export const onRequest = defineMiddleware(async ({ url, cookies, redirect }, next) => {
  const isProtected = PROTECTED_ROUTES.some(route =>
    url.pathname.startsWith(route)
  );

  if (isProtected) {
    const token = cookies.get('auth-token')?.value;
    if (!token) {
      return redirect(`/login?returnUrl=${url.pathname}`);
    }

    try {
      const user = await verifyToken(token);
      // ส่ง user ไปยัง page ผ่าน locals
      context.locals.user = user;
    } catch {
      return redirect('/login');
    }
  }

  return next();
});

Locals

// src/env.d.ts
declare namespace App {
  interface Locals {
    user?: {
      id: string;
      name: string;
      role: string;
    };
  }
}
---
// src/pages/dashboard.astro
const { user } = Astro.locals;
---

<h1>สวัสดี {user?.name}</h1>

Sequence Middleware

import { sequence } from 'astro:middleware';

const auth = defineMiddleware(async (context, next) => {
  // auth logic
  return next();
});

const logging = defineMiddleware(async (context, next) => {
  // logging logic
  return next();
});

export const onRequest = sequence(logging, auth);

i18n Middleware

export const onRequest = defineMiddleware(async ({ url, redirect }, next) => {
  const lang = url.pathname.split('/')[1];
  const supportedLangs = ['th', 'en', 'ja'];

  if (!supportedLangs.includes(lang)) {
    return redirect(`/th${url.pathname}`);
  }

  return next();
});

สรุป

Middleware ใน Astro ทำงานได้ทั้ง static และ SSR mode ช่วยให้จัดการ cross-cutting concerns ได้อย่างสะอาดครับ