Next.js 16 Middleware ปี 2026: Edge Runtime, การยืนยันตัวตน และคำถามสัมภาษณ์งาน

คู่มือฉบับสมบูรณ์เกี่ยวกับ Next.js 16 Middleware ในปี 2026 เรียนรู้การทำงานของ Edge Runtime การใช้งานระบบยืนยันตัวตน path matching และเตรียมตัวสำหรับคำถามสัมภาษณ์ frontend

Next.js 16 Middleware Edge Runtime Authentication

Next.js 16 Middleware ทำงานก่อนทุก request จะถึงเซิร์ฟเวอร์ ทำให้เป็นแนวป้องกันแรกสำหรับการยืนยันตัวตน การแปลภาษา และการจัดการ request การเข้าใจ middleware เป็นสิ่งจำเป็นสำหรับการสร้างแอปพลิเคชัน production และเป็นหัวข้อที่มักถูกถามในการสัมภาษณ์งาน frontend

Middleware ทำงานที่ Edge

Next.js 16 Middleware ทำงานใน Edge Runtime ตามค่าเริ่มต้น หมายความว่ามันทำงานที่ data center ที่ใกล้ผู้ใช้ที่สุดโดยมี cold start น้อยกว่าหนึ่งมิลลิวินาที ทำให้เหมาะอย่างยิ่งสำหรับการตรวจสอบการยืนยันตัวตนและ redirect ที่ต้องเกิดขึ้นก่อนที่หน้าจะถูก render

การทำงานของ Next.js 16 Middleware

Middleware ใน Next.js 16 สกัดกั้น request ก่อนที่จะถึง route handler หรือ component ของหน้า ไฟล์ middleware ต้องวางไว้ที่ root ของโปรเจกต์ (ข้างๆ app/ หรือ pages/) และ export ฟังก์ชันเริ่มต้นที่รับออบเจ็กต์ NextRequest

ข้อจำกัดของ Edge Runtime หมายความว่า middleware ไม่สามารถใช้ API ของ Node.js เช่น fs หรือ Buffer ได้ มันทำงานบน V8 isolates คล้ายกับ Cloudflare Workers ซึ่งช่วยให้กระจายได้ทั่วโลกแต่จำกัด API ที่ใช้ได้เฉพาะ Web Standards

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Access request headers, cookies, and URL
  const token = request.cookies.get('session')?.value
  const pathname = request.nextUrl.pathname

  // Log for debugging (visible in Vercel logs)
  console.log(`Middleware: ${request.method} ${pathname}`)

  // Continue to the route handler
  return NextResponse.next()
}

// Configure which paths trigger middleware
export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}

การกำหนด matcher ใช้ไวยากรณ์คล้าย regex เพื่อกำหนดว่า path ใดจะเรียกใช้ middleware หากไม่มีการกำหนดนี้ middleware จะทำงานกับทุก request รวมถึง static assets

รูปแบบการยืนยันตัวตนด้วย Next.js Middleware

Middleware เหมาะสมอย่างยิ่งสำหรับการยืนยันตัวตนเพราะทำงานก่อนที่โค้ดหน้าใดๆ จะถูกเรียกใช้ ผู้ใช้ที่ไม่มี session ที่ถูกต้องจะไม่เห็นเนื้อหาที่ถูกป้องกันเลย แม้แต่เพียงชั่วขณะ นี่แตกต่างจากการตรวจสอบ auth ฝั่ง client ที่อาจแสดงเนื้อหาที่ถูกป้องกันก่อนที่จะ redirect

รูปแบบต่อไปนี้ตรวจสอบ session token และเปลี่ยนเส้นทางผู้ใช้ที่ไม่ได้รับการยืนยันตัวตน สามารถทำงานร่วมกับผู้ให้บริการ auth ใดก็ได้ที่เก็บข้อมูล session ใน cookies หรือ headers

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const protectedPaths = ['/dashboard', '/settings', '/profile']
const authPaths = ['/login', '/signup']

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl
  const sessionToken = request.cookies.get('session')?.value

  // Check if path requires authentication
  const isProtectedPath = protectedPaths.some(path => 
    pathname.startsWith(path)
  )
  const isAuthPath = authPaths.some(path => 
    pathname.startsWith(path)
  )

  // Validate session token (call auth service)
  const isValidSession = sessionToken 
    ? await validateSession(sessionToken)
    : false

  // Redirect unauthenticated users to login
  if (isProtectedPath && !isValidSession) {
    const loginUrl = new URL('/login', request.url)
    loginUrl.searchParams.set('callbackUrl', pathname)
    return NextResponse.redirect(loginUrl)
  }

  // Redirect authenticated users away from auth pages
  if (isAuthPath && isValidSession) {
    return NextResponse.redirect(new URL('/dashboard', request.url))
  }

  return NextResponse.next()
}

async function validateSession(token: string): Promise<boolean> {
  // Call auth API endpoint or decode JWT
  // Edge-compatible: use fetch, not Node.js crypto
  try {
    const response = await fetch('https://api.example.com/validate', {
      headers: { Authorization: `Bearer ${token}` },
    })
    return response.ok
  } catch {
    return false
  }
}

พารามิเตอร์ callbackUrl เก็บปลายทางเดิมไว้ ดังนั้นผู้ใช้จะไปยังหน้าที่ร้องขอเดิมหลังจากเข้าสู่ระบบ

Path Matching และการกำหนด Matcher

การกำหนด matcher กำหนดว่า request ใดจะเรียกใช้ middleware การกำหนดผิดอาจนำไปสู่ปัญหาด้านประสิทธิภาพ (middleware ทำงานกับทุก static asset) หรือช่องโหว่ด้านความปลอดภัย (path ที่ถูกป้องกันไม่เรียกใช้การตรวจสอบ auth)

Next.js 16 รองรับสามรูปแบบของ matcher: string path อย่างง่าย, รูปแบบ path พร้อมพารามิเตอร์ และรูปแบบคล้าย regex พร้อม negative lookahead

middleware.tstypescript
// Option 1: Simple string paths
export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*'],
}

// Option 2: Exclude static assets with negative lookahead
export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico|public/).*)'],
}

// Option 3: Conditional matching with has/missing
export const config = {
  matcher: [
    {
      source: '/api/:path*',
      has: [{ type: 'header', key: 'Authorization' }],
    },
    {
      source: '/dashboard/:path*',
      missing: [{ type: 'cookie', key: 'session' }],
    },
  ],
}

เงื่อนไข has และ missing ในตัวเลือกที่ 3 เพิ่มตรรกะก่อนที่ middleware จะทำงาน นี่มีประสิทธิภาพมากกว่าการตรวจสอบภายในฟังก์ชัน middleware

พร้อมที่จะพิชิตการสัมภาษณ์ React / Next.js แล้วหรือยังครับ?

ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ

การจัดการ Request และ Response ใน Middleware

นอกเหนือจากการยืนยันตัวตน middleware สามารถแก้ไข request ก่อนที่จะถึง route handler และ response ก่อนที่จะถึง client กรณีใช้งานทั่วไปรวมถึงการเพิ่ม security headers การเขียน URL ใหม่สำหรับ A/B testing และการแทรกข้อมูล geolocation

คลาส NextResponse มีเมธอดสำหรับแต่ละประเภทของการแก้ไข Rewrite เปลี่ยนปลายทางโดยไม่เปลี่ยน URL ของเบราว์เซอร์ ในขณะที่ redirect อัปเดตทั้งคู่

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const response = NextResponse.next()

  // Add security headers to all responses
  response.headers.set('X-Frame-Options', 'DENY')
  response.headers.set('X-Content-Type-Options', 'nosniff')
  response.headers.set(
    'Referrer-Policy', 
    'strict-origin-when-cross-origin'
  )

  // Inject geolocation into request headers for route handlers
  const geo = request.geo
  if (geo?.country) {
    response.headers.set('x-user-country', geo.country)
    response.headers.set('x-user-city', geo.city ?? 'unknown')
  }

  return response
}

ข้อมูล geolocation (request.geo) ถูกเติมโดย Vercel Edge Network การ deploy แบบ self-hosted ต้องกำหนดค่านี้ผ่านผู้ให้บริการ hosting หรือใช้บริการ geolocation IP ของบุคคลที่สาม

URL Rewriting สำหรับ A/B Testing และ Feature Flags

Middleware rewrite ช่วยให้สามารถให้บริการหน้าที่แตกต่างกันตาม cookies, headers หรือการกำหนดแบบสุ่มโดยที่ client ไม่รู้ รูปแบบนี้ขับเคลื่อน framework A/B testing และการเปิดตัวฟีเจอร์แบบค่อยเป็นค่อยไป

Rewrite เกิดขึ้นที่ edge ดังนั้นทั้งสองเวอร์ชันมี URL เดียวกันและได้รับประโยชน์จาก edge caching เมื่อเหมาะสม

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl

  // Check for existing variant assignment
  let variant = request.cookies.get('ab-variant')?.value

  // Assign variant if not set (50/50 split)
  if (!variant && pathname === '/pricing') {
    variant = Math.random() < 0.5 ? 'control' : 'treatment'
    const response = NextResponse.rewrite(
      new URL(`/pricing/${variant}`, request.url)
    )
    response.cookies.set('ab-variant', variant, {
      maxAge: 60 * 60 * 24 * 30, // 30 days
      httpOnly: true,
    })
    return response
  }

  // Rewrite to assigned variant
  if (variant && pathname === '/pricing') {
    return NextResponse.rewrite(
      new URL(`/pricing/${variant}`, request.url)
    )
  }

  return NextResponse.next()
}

Cookie รักษาการกำหนดเวอร์ชัน ทำให้ผู้ใช้เห็นเวอร์ชันเดียวกันเมื่อกลับมาเยี่ยมชม การหมดอายุ 30 วันสมดุลระหว่างความสอดคล้องของการทดลองกับความสามารถในการกำหนดผู้ใช้ใหม่ให้กับการทดลองใหม่

ข้อจำกัดของ Edge Runtime และวิธีแก้ไข

Edge Runtime แลกเปลี่ยนความเข้ากันได้ของ Node.js กับการกระจายทั่วโลกและ cold start ที่รวดเร็ว Middleware ไม่สามารถ import โมดูลเฉพาะของ Node.js ซึ่งส่งผลกระทบต่อไลบรารีเช่น bcrypt, jsonwebtoken (เมื่อใช้ RS256) และ database clients ที่ใช้ TCP sockets

เอกสาร Edge Runtime ของ Next.js ระบุ API ที่รองรับ Web Crypto, fetch และ Web Platform APIs ส่วนใหญ่ทำงานได้ การคำนวณหนักควรย้ายไปยัง API routes ที่ทำงานใน Node.js

middleware.ts - JWT validation without jsonwebtokentypescript
import { jwtVerify } from 'jose' // Edge-compatible JWT library
import type { NextRequest } from 'next/server'

const JWT_SECRET = new TextEncoder().encode(process.env.JWT_SECRET!)

export async function middleware(request: NextRequest) {
  const token = request.cookies.get('token')?.value

  if (!token) {
    return redirectToLogin(request)
  }

  try {
    // jose library works in Edge Runtime
    const { payload } = await jwtVerify(token, JWT_SECRET)
    
    // Token is valid, check expiration
    if (payload.exp && payload.exp < Date.now() / 1000) {
      return redirectToLogin(request)
    }

    return NextResponse.next()
  } catch {
    // Invalid token signature or format
    return redirectToLogin(request)
  }
}

function redirectToLogin(request: NextRequest) {
  const url = new URL('/login', request.url)
  url.searchParams.set('callbackUrl', request.nextUrl.pathname)
  return NextResponse.redirect(url)
}

ไลบรารี jose มีการดำเนินการ JWT ที่เข้ากันได้กับ Edge มันใช้ Web Crypto ภายใน หลีกเลี่ยงโมดูล crypto ของ Node.js

คำถามสัมภาษณ์ทั่วไปเกี่ยวกับ Next.js Middleware

ผู้สัมภาษณ์ถามเกี่ยวกับ middleware เพื่อประเมินความเข้าใจเกี่ยวกับวงจรชีวิตของ request รูปแบบความปลอดภัย และข้อจำกัดของ Edge computing คำถามเหล่านี้ปรากฏในตำแหน่ง frontend และ fullstack ระดับสูงที่ทำงานกับ Next.js

Middleware ทำงานที่ไหนในวงจรชีวิตของ request?

Middleware ทำงานหลังจาก request มาถึงเซิร์ฟเวอร์ Next.js แต่ก่อน route matching หรือการ render หน้า บน Vercel มันทำงานที่ Edge หมายความว่า data center ที่ใกล้ผู้ใช้ที่สุด ตำแหน่งนี้ทำให้เหมาะสำหรับการยืนยันตัวตนและ redirect เพราะ request ที่ไม่ถูกต้องไม่เคยถึง origin server

Middleware ทำอะไรไม่ได้เมื่อเทียบกับ API routes?

Middleware ทำงานใน Edge Runtime ไม่ใช่ Node.js มันไม่สามารถใช้โมดูลในตัวของ Node.js (fs, path, crypto กับอัลกอริทึมบางตัว), database clients ที่ใช้ TCP หรือแพ็คเกจ npm ที่พึ่งพา API ของ Node.js การคำนวณหนักควรทำใน API routes หรือ Server Components

จะจัดการการยืนยันตัวตนใน middleware โดยไม่ blocking อย่างไร?

รูปแบบรวมถึงการตรวจสอบ session cookie การตรวจสอบกับ auth endpoint หรือโดยการยืนยันลายเซ็น JWT และ redirect หากไม่ถูกต้อง เพื่อหลีกเลี่ยงการ block ทุก request ใช้การกำหนด matcher เพื่อเรียกใช้ middleware เฉพาะบน path ที่ถูกป้องกัน การตรวจสอบ JWT แบบ stateless เร็วกว่าการเรียกบริการ auth ภายนอกทุก request

จะเกิดอะไรขึ้นถ้า middleware โยน error?

Error ที่ไม่ได้จัดการใน middleware ส่งคืน response 500 ไปยัง client หน้าไม่เคยถูก render การห่อตรรกะ middleware ใน try-catch และส่งคืน response สำรอง (มักจะเป็น NextResponse.next()) ป้องกันความล้มเหลวของ request ทั้งหมด การบันทึก error ก่อนดำเนินการต่อช่วยในการ debug

สำหรับการฝึกฝนเชิงลึกเกี่ยวกับแนวคิดเหล่านี้ โมดูล คำถามสัมภาษณ์ Next.js Middleware และ Auth ครอบคลุมสถานการณ์เพิ่มเติม

การ Debug Middleware ใน Development และ Production

บั๊ก middleware ยากต่อการติดตามเพราะโค้ดทำงานที่ edge ไม่ใช่ใน browser DevTools โหมด development แสดง log ของ middleware ใน terminal แต่ production ต้องการโครงสร้างพื้นฐาน logging ที่เหมาะสม

แนวทางต่อไปนี้บันทึกการทำงานของ middleware พร้อมบริบทที่เพียงพอสำหรับ debug โดยไม่เปิดเผยข้อมูลที่ละเอียดอ่อน

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const start = Date.now()
  const requestId = crypto.randomUUID()

  // Log request start
  console.log(JSON.stringify({
    type: 'middleware_request',
    requestId,
    method: request.method,
    path: request.nextUrl.pathname,
    userAgent: request.headers.get('user-agent')?.slice(0, 100),
    country: request.geo?.country,
  }))

  // Process request
  const response = processRequest(request)

  // Log completion
  console.log(JSON.stringify({
    type: 'middleware_response',
    requestId,
    duration: Date.now() - start,
    status: response.status,
  }))

  // Pass request ID to route handlers
  response.headers.set('x-request-id', requestId)
  return response
}

function processRequest(request: NextRequest): NextResponse {
  // Middleware logic here
  return NextResponse.next()
}

บน Vercel log เหล่านี้ปรากฏในแท็บ Functions การ deploy แบบ self-hosted ควรส่ง log ไปยังบริการเช่น Datadog หรือใช้ structured logging ที่แพลตฟอร์ม hosting สามารถประมวลผลได้

แนวปฏิบัติที่ดีสำหรับประสิทธิภาพ Middleware

Middleware ทำงานกับทุก request ที่ตรงกัน ฟังก์ชัน middleware ที่ช้าเพิ่มความหน่วงให้ทุกการโหลดหน้า เป้าหมายคือทำให้การทำงานของ middleware เสร็จภายใน 5ms สำหรับ request ส่วนใหญ่

  • ลดการดำเนินการ async: แต่ละ await เพิ่มความหน่วง Cache ผลลัพธ์การตรวจสอบเมื่อเป็นไปได้
  • ใช้การกำหนด matcher: ยกเว้น static assets และ path สาธารณะที่ไม่ต้องการตรรกะ middleware
  • หลีกเลี่ยงการเรียก external ทุก request: ตรวจสอบ JWT ในเครื่องแทนการเรียกบริการ auth Cache ผลลัพธ์ใน cookies เมื่อเหมาะสม
  • รักษาขนาด bundle ให้เล็ก: Middleware มีขีดจำกัดขนาด bundle ของตัวเอง (1MB บน Vercel) Import เฉพาะสิ่งที่จำเป็น

หน้าเทคโนโลยี React Next.js ที่ /technologies/react-next ครอบคลุมแนวคิดที่เกี่ยวข้องเช่น Server Components และรูปแบบ data fetching ที่เสริมความรู้เรื่อง middleware

เริ่มฝึกซ้อมเลย!

ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ

Checklist Next.js 16 Middleware สำหรับ Production

  • วาง middleware ที่ root ของโปรเจกต์เป็น middleware.ts ไม่ใช่ภายใน app/ หรือ pages/
  • กำหนด matcher เพื่อยกเว้น _next/static, _next/image และ assets สาธารณะจากการทำงานของ middleware
  • ใช้ไลบรารีที่เข้ากันได้กับ Edge สำหรับการตรวจสอบ JWT เช่น jose แทน jsonwebtoken
  • เก็บ callback URL ในพารามิเตอร์ query เมื่อ redirect ไปยังหน้า login เพื่อให้ผู้ใช้กลับไปยังปลายทางที่ต้องการ
  • เพิ่ม security headers ใน middleware เพื่อให้การใช้งานสม่ำเสมอในทุก route
  • บันทึกการทำงานของ middleware พร้อม request ID เพื่อติดตาม request ผ่านระบบ
  • รักษาการเรียก API ภายนอกให้น้อยที่สุดโดยตรวจสอบ token ในเครื่องและเก็บข้อมูลผู้ใช้ใน signed cookies
ชาเลนจ์ประจำวัน

คุณหาบั๊กใน React / Next.js เจอไหม

โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

Anthony Fillion-Maillet

เขียนโดย

Anthony Fillion-Maillet

ผู้ก่อตั้ง SharpSkill

เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่

อัปเดตเมื่อ 20 กันยายน 2569

แท็ก

#nextjs
#middleware
#edge-runtime
#authentication
#interview

แชร์

บทความที่เกี่ยวข้อง