Panduan Praktis Cara Membuat Protected Route Next Js di App Router

Cara membuat protected route Next.js di App Router yang benar adalah memeriksa cookie sesi di middleware.ts, lalu memverifikasi ulang sesi tersebut di Layout atau Page Server Component. Middleware saja tidak cukup karena hanya membaca cookie, bukan membuktikan token valid.

Authentication menjawab siapa pengguna. Authorization menjawab apa yang boleh ia akses. Middleware menangani pengalihan cepat, Server Component menangani keputusan akhir.

Pola Protected Route yang Benar di App Router

Gunakan tiga lapis sesuai fungsinya. Middleware memblokir akses awal ke /dashboard dan meneruskan ke /login. Layout server memverifikasi sesi sebelum merender UI privat. Client hanya membaca status yang sudah diputuskan server.

  • Middleware: cek keberadaan cookie sesi dan redirect.
  • Layout atau Page server: verify token dan cek role ke database.
  • Client Component: tampilkan loading atau panggil router.replace hanya sebagai fallback UX.

Langkah Membuat Protected Route Next Js

Ikuti urutan ini agar tidak ada celah antara redirect dan render.

1. Petakan rute private seperti /dashboard/:path* dan rute public seperti /login, /register.
2. Buat middleware.ts di root proyek untuk membaca cookie sesi.
3. Redirect pengguna tanpa sesi ke /login?callbackUrl=/dashboard.
4. Verifikasi ulang sesi di app/dashboard/layout.tsx memakai Server Component.
5. Tangani logout dengan menghapus cookie di server dan arahkan token expired ke login dengan pesan sesi habis.

Contoh Kode Middleware dan Pengecekan Server

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const session = request.cookies.get('session')?.value;
  const isPrivate = request.nextUrl.pathname.startsWith('/dashboard');
  if (isPrivate && !session) {
    const url = new URL('/login', request.url);
    url.searchParams.set('callbackUrl', request.nextUrl.pathname);
    return NextResponse.redirect(url);
  }
  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*'],
};
// app/dashboard/layout.tsx
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';

export default async function DashboardLayout({ children }) {
  const session = (await cookies()).get('session')?.value;
  if (!session) redirect('/login');
  // verify token di sini sebelum render children
  return <>{children}</>;
}
  • Gunakan flag httpOnly agar tidak bisa dibaca JavaScript.
  • Aktifkan secure di production dan sameSite=lax.
  • Set expiry singkat dan perpanjang lewat refresh token server.

Kesalahan Umum dan Tabel Perbaikan

Masalah Penyebab Solusi
Halaman privat sempat tampil Cek token hanya di client Pindah verifikasi ke middleware dan server
Token palsu lolos Decode tanpa verify signature Verify JWT di server tiap request
User logout masih bisa akses Tidak validasi sesi server Cek ulang sesi di layout server

FAQ

Apakah cukup cek auth di Client Component?

Tidak. Kode client bisa dimodifikasi, verifikasi akhir harus di middleware dan Server Component.

Di mana menyimpan token agar aman?

Simpan session ID di cookie httpOnly, bukan di localStorage.