Cara Mengatasi 419 Page Expired di Laravel

Error 419 Page Expired di Laravel hampir selalu berarti request gagal lolos CSRF atau session tidak cocok. Jawaban singkatnya: cek @csrf, session, domain, dan apakah request AJAX mengirim token.

Masalah ini sangat umum pada form login, logout, register, dan form CRUD. Di local development kadang terasa acak, tetapi di production biasanya berkaitan dengan konfigurasi session, domain, atau request AJAX yang tidak mengirim token.

Jawaban Singkat

Kalau form Blade tiba-tiba berakhir di halaman error 419, urutannya begini:

  1. Pastikan form POST, PUT, PATCH, atau DELETE punya @csrf.
  2. Pastikan session masih aktif dan cookie tersimpan.
  3. Samakan domain, subdomain, dan protocol http / https.
  4. Kalau pakai AJAX, kirim header CSRF.
  5. Setelah mengubah .env, jalankan php artisan optimize:clear.

Kapan Error Ini Biasanya Muncul?

  • Saat submit form Blade tanpa @csrf
  • Saat user terlalu lama diam di halaman lalu baru submit form
  • Saat request AJAX tidak mengirim header CSRF
  • Saat aplikasi berpindah domain, subdomain, atau protocol
  • Saat konfigurasi session berubah, tapi cache config belum dibersihkan

Penyebab Paling Umum

1. Form Tidak Menyertakan CSRF Token

<form method="POST" action="/login">
    <input type="email" name="email">
    <button type="submit">Masuk</button>
</form>

Form di atas akan memicu 419 karena request POST tidak membawa token CSRF.

Perbaikan:

<form method="POST" action="/login">
    @csrf

    <input type="email" name="email">
    <button type="submit">Masuk</button>
</form>

2. Session Expired

Token CSRF Laravel terkait dengan session user. Jika session habis masa berlakunya, token lama ikut tidak valid.

3. Domain atau Protocol Tidak Konsisten

Contohnya:

  • aplikasi dibuka dari http://app.test, tetapi form submit ke https://app.test
  • user login di www.domain.com, lalu submit form di domain.com

4. Request AJAX Tidak Mengirim Token

fetch() atau request frontend kustom harus mengirim X-CSRF-TOKEN atau nilai _token.

5. Konfigurasi Session Salah

Masalah umum:

  • SESSION_DOMAIN tidak cocok
  • SESSION_SECURE_COOKIE=true dipakai di HTTP biasa
  • session driver tidak tersimpan dengan baik

Langkah Diagnosis

  1. Pastikan form POST memakai @csrf.
  2. Cek apakah cookie session benar-benar ada di browser.
  3. Bandingkan domain dan protocol halaman dengan request submit.
  4. Untuk AJAX, lihat tab Network dan pastikan header/token ikut terkirim.
  5. Jika baru mengubah .env, bersihkan cache konfigurasi Laravel.
Mulai dari Kasus Paling Sering

Kalau 419 muncul di form Blade biasa, periksa @csrf dulu. Itu penyebab paling umum dan paling cepat diperbaiki.

Langkah Fix

1. Tambahkan @csrf di Semua Form POST, PUT, PATCH, dan DELETE

<form method="POST" action="/login">
    @csrf

    <input type="email" name="email">
    <button type="submit">Masuk</button>
</form>

2. Atur Request AJAX Agar Mengirim Token

Tambahkan meta tag di layout:

<meta name="csrf-token" content="{{ csrf_token() }}">

Lalu kirim token saat request:

const token = document
  .querySelector('meta[name="csrf-token"]')
  ?.getAttribute('content');

await fetch('/posts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-TOKEN': token,
  },
  body: JSON.stringify({ title: 'Halo Laravel' }),
});

3. Pastikan Session Environment Benar

Contoh nilai yang sering perlu dicek:

APP_URL=https://belajarphp.test
SESSION_DOMAIN=belajarphp.test
SESSION_SECURE_COOKIE=true

Kalau masih memakai HTTP lokal, jangan paksa SESSION_SECURE_COOKIE=true.

4. Bersihkan Cache Setelah Ubah Konfigurasi

php artisan optimize:clear

Kalau kamu baru mengubah .env, langkah ini sering langsung menyelesaikan masalah.

5. Tangani Form yang Bisa Lama Terbuka

Untuk form admin atau form panjang, beri pesan ke user bahwa session bisa berakhir bila halaman terlalu lama dibiarkan terbuka.

Contoh Sebelum dan Sesudah

Sebelum

<form method="POST" action="/produk">
    <input type="text" name="nama">
    <button type="submit">Simpan</button>
</form>

Sesudah

<form method="POST" action="/produk">
    @csrf

    <input type="text" name="nama">
    <button type="submit">Simpan</button>
</form>

Kesalahan yang Sering Terjadi

419 Hanya Terjadi di Production

Biasanya terkait:

  • SESSION_DOMAIN
  • SESSION_SECURE_COOKIE
  • reverse proxy atau HTTPS termination
  • config cache belum dibersihkan

419 Muncul Setelah Login Lama Didiamkan

Ini biasanya session timeout biasa. Solusinya bukan mematikan CSRF, tetapi memperbarui halaman atau login ulang.

419 di AJAX, Tapi Form Biasa Aman

Berarti request JavaScript tidak mengirim token dengan benar.

SESSION_SECURE_COOKIE=true di Local HTTP

Kalau app masih dibuka lewat http://, cookie secure bisa gagal tersimpan dan request berikutnya kehilangan session.

Pencegahan

  1. Jadikan @csrf kebiasaan di semua form yang mengubah data.
  2. Pakai layout utama yang selalu menyertakan meta CSRF token.
  3. Samakan domain dan protocol antara halaman, asset, dan endpoint submit.
  4. Setelah mengubah .env, jalankan clear cache Laravel.
  5. Jangan menonaktifkan proteksi CSRF hanya demi "memperbaiki" 419.

Bacaan Terkait

FAQ

Apakah 419 sama dengan 403?

Tidak. Di Laravel, 419 biasanya dipakai untuk masalah CSRF token atau session yang expired, bukan untuk otorisasi.

Apakah aman menonaktifkan CSRF?

Tidak untuk route web biasa. Proteksi CSRF dibuat untuk mencegah request palsu dari situs lain.

Bagaimana dengan webhook dari layanan pihak ketiga?

Webhook biasanya tidak memakai middleware web seperti form browser biasa. Pisahkan endpoint webhook dengan pendekatan yang memang sesuai, jangan menyamakan semua request dengan form user.