Pendahuluan

Problem utama yang dijawab artikel ini adalah: bagaimana memperkuat autentikasi dan sesi di App Router Next.js tanpa hanya mengandalkan fitur default? Dalam Next.js App Router, bagian seperti secret penyimpanan, session cookie, dan token autentikasi tetap rentan bila tidak difortifikasi. Artikel ini langsung memberikan pendekatan protektif untuk secret handling, perlindungan cookie sesi, validasi payload auth, dan mitigasi penyalahgunaan seperti rate limit atau reuse token.

Contoh diberikan dalam konteks middleware dan edge function yang relevan agar pembaca bisa langsung menerapkan di proyek Next.js.

Hardening Secret Handling

Pertama, tempatkan semua secret (API key, JWT signing key) di storage yang aman seperti Environment Variables dalam hosting provider atau secrets manager, tidak dalam repo. Pastikan variabel hanya dibaca di server-side dan tidak pernah diekspor ke bundler client. Gunakan pola berikut:

const jwtSecret = process.env.JWT_SECRET;
if (!jwtSecret) {
  throw new Error('ENV SECRET missing');
}

Logika validasi awal seperti di atas mencegah server berjalan tanpa konfigurasi yang benar. Selanjutnya, batasi scope secret dengan role-based access pada platform CI/CD, dan rotasi secret secara berkala.

Untuk menyembunyikan secret dari bundle client, pastikan semua import yang menggunakan secret hanya ada di folder server (misalnya src/app/api/…). Next.js App Router otomatis mengisolasi file server dari bundling klien jika menggunakan file server-only (misalnya with "use server" atau file dalam /api). Hindari menyimpan secret di file .env publik atau .env.local yang ikut di-commit.

Proteksi Session Cookie

Session cookie harus dikonfigurasi agar tidak mudah disadap. Gunakan flag HttpOnly, Secure, dan scope path atau domain yang sesuai. Contoh middleware untuk menetapkan cookie aman:

import { NextResponse } from 'next/server';

export function middleware(req) {
  const response = NextResponse.next();
  response.cookies.set({
    name: 'next_session',
    value: 'hash+payload',
    httpOnly: true,
    secure: req.nextUrl.protocol === 'https',
    sameSite: 'lax',
    path: '/',
    maxAge: 60 * 60 * 24,
  });
  return response;
}

Gunakan pendekatan signed atau encrypted cookie untuk memastikan integritas. Jika menggunakan JWT sebagai session token, pastikan tidak menyimpannya di localStorage agar tidak terkena XSS. Gunakan cookie dengan SameSite yang sesuai (biasanya lax untuk autentikasi dasar) dan tambahkan pengaturan CSP serta sanitasi input untuk meminimalisasi XSS.

Perhatikan trade-off antara durasi session dan UX. Durasi lama memperbesar window serangan replay, sementara terlalu pendek dapat membuat user merasa terganggu. Pastikan cookie invalidated saat logout, baik dari server (misalnya dengan flag expirations) maupun client (menghapus cookie).

Validasi Payload Auth

Validasi payload auth memperkecil celah manipulasi token atau data user. Saat menerima request dari middleware atau API route, lakukan:

  • Parsing strict JSON dengan schema validation (misalnya Zod atau Yup). Pastikan token memiliki struktur yang diharapkan.
  • Verifikasi signature JWT dengan secret/keys yang sama yang digunakan saat signing.
  • Periksa klaim tambahan seperti exp, aud, atau iss untuk memastikan token cocok konteks aplikasi.

Contoh validasi dengan Zod di route handler:

import { z } from 'zod';

const authPayloadSchema = z.object({
  userId: z.string().uuid(),
  roles: z.array(z.string()),
});

export async function POST(req) {
  const payload = await req.json();
  const parsed = authPayloadSchema.safeParse(payload);
  if (!parsed.success) {
    return new Response('Invalid payload', { status: 400 });
  }
  // lanjutkan logic autentikasi
}

Pastikan-fetch data tambahan (misalnya dari DB) hanya dilakukan setelah payload tervalidasi. Memperketat payload membuat kesalahan parsing atau payload injection dapat segera dihentikan.

Mitigasi Abuse: Rate Limit dan Token Reuse

proteksi terhadap abuse penting untuk mencegah brute force login, token stuffing, atau replay. Untuk Next.js App Router, letakkan middleware di lapisan paling depan:

import { NextResponse } from 'next/server';
import { getRateLimit } from '@/lib/rate-limit';

export async function middleware(req) {
  const limit = await getRateLimit(req.ip);
  if (!limit.ok) {
    return new NextResponse('Too Many Requests', { status: 429 });
  }
  return NextResponse.next();
}

Implementasi getRateLimit bisa menggunakan Redis atau in-memory store sesuai kebutuhan. Pastikan juga token reuse dicegah dengan mengelola blacklist token atau menandai token yang sudah digunakan sekali (misalnya refresh token one-time).

Jika menggunakan refresh token, simpan metadata session (device, timestamp) di server dan batasi satu sesi per device untuk memudahkan revokasi. Audit trail membantu menelusuri reuse token.

Implementasi Middleware dan Edge Function

Next.js App Router memungkinkan middleware berjalan di Node.js atau Edge runtime. Gunakan middleware untuk pemeriksaan ringan (rate limit, cookie check), sementara operasi berat (DB lookup) tetap di route handler. Contoh middleware sederhana mengecek cookie dan meneruskan header ke handler:

import { NextResponse } from 'next/server';

export function middleware(req) {
  const session = req.cookies.get('next_session');
  if (!session) {
    return NextResponse.redirect(new URL('/login', req.url));
  }
  const response = NextResponse.next();
  response.headers.set('x-session-checked', '1');
  return response;
}

Jika perlu menjalankan di edge (misalnya untuk global rate limit), pastikan dependensi mendukung edge runtime dan hindari penggunaan API Node.js yang tidak tersedia. Middleware juga bisa melakukan delegasi ke edge function untuk validasi token sebelum mencapai route utama.

Checklist Audit Proteksi App Router

  • Semua secret tersimpan di environment/secret manager, tidak di-bundle client.
  • Cookie sesi punya HttpOnly, Secure, SameSite tepat.
  • Payload auth tervalidasi dengan schema dan klaim JWT diverifikasi.
  • Rate limit atau throttling diterapkan (middleware/edge) di titik awal.
  • Token reuse ditangani via blacklist, metadata sesi, atau refresh policy.
  • Middleware hanya menangani tugas ringan tanpa akses ke API Node.js yang tidak tersedia di edge jika dijalankan di sana.
  • Audit log dibuat untuk deteksi anomali dan debugging.

Checklist ini bisa dijadikan dasar audit sebelum deploy ke produksi. Pastikan terus di-update ketika kebutuhan autentikasi berubah.

Kesimpulan

Dengan menggabungkan secret hardening, proteksi cookie sesi, validasi payload, dan mitigasi abuse dalam App Router Next.js, Anda membentuk lapisan perlindungan autentikasi yang komprehensif. Gunakan middleware untuk perlindungan cepat, edge function untuk latensi rendah, dan selalu audit konfigurasi. Pendekatan ini menjaga user data tetap aman sekaligus memberikan landasan yang kuat untuk pengembangan berkelanjutan.