M
Mr Sugiarto
Developer
18 Sep 2026 3 min read

Login sudah bisa dilakukan, tapi belum ada efeknya — guest yang tidak login pun masih bebas membuat, mengubah, atau menghapus post. Episode ini kita tutup celah itu dengan middleware.

Screenshot: Guest yang mencoba akses /posts/create otomatis dialihkan ke halaman login. Guest yang mencoba akses /posts/create otomatis dialihkan ke halaman login.

Apa itu middleware?

Middleware adalah lapisan yang "menyaring" request sebelum sampai ke controller — cocok untuk aturan seperti "harus login", "harus admin", atau logging. Laravel sudah menyediakan middleware auth bawaan yang otomatis redirect ke halaman login kalau user belum authenticated.

Memisahkan route publik dan route terproteksi

// Protected post routes - only logged-in users can create, edit, or delete
// Registered before the public "show" route so /posts/create isn't matched as /posts/{post}
Route::middleware('auth')->group(function () {
    Route::resource('posts', PostController::class)->except(['index', 'show']);
});

// Public post routes - anyone can browse
Route::resource('posts', PostController::class)->only(['index', 'show']);

Route::resource(...)->except([...]) dan ->only([...]) membiarkan kita memecah 7 route resource menjadi grup terpisah — index dan show tetap publik (siapa saja boleh baca), sedangkan create, store, edit, update, destroy dibungkus middleware auth.

Jebakan urutan route yang wajib diketahui

Ini bagian pentingnya: grup auth harus didaftarkan LEBIH DULU sebelum route publik. Kenapa?

URL /posts/create secara pattern mirip dengan /posts/{post} (route show). Kalau route show didaftarkan lebih dulu, Laravel akan mencocokkan /posts/create ke pattern /posts/{post} duluan — menganggap create sebagai nilai ID, lalu gagal karena tidak ada post dengan ID "create" (hasilnya 404 yang membingungkan).

Dengan mendaftarkan grup auth (yang berisi route create) lebih dulu, Laravel mencocokkan /posts/create ke route spesifik itu sebelum sempat dicoba cocokkan ke pattern {post} yang lebih generic.

Menyembunyikan tombol berdasarkan status login

Middleware melindungi di level route, tapi UI juga sebaiknya tidak menampilkan tombol yang tidak bisa dipakai:

@auth
    <a class="nav-link" href="{{ route('posts.create') }}">New Post</a>
@endauth
@auth
    <div class="mt-4 d-flex gap-2">
        <a href="{{ route('posts.edit', $post) }}" class="btn btn-secondary">Edit</a>
        <!-- form delete -->
    </div>
@endauth

@auth adalah kebalikan dari @guest yang kita pakai episode sebelumnya — kontennya hanya tampil kalau user sudah login.

Testing: guest ditolak, user login diterima

# Guest - harus redirect ke /login (302)
curl -o /dev/null -w "%{http_code}\n" http://laravel13-blog-dasar.test/posts/create

# Setelah login (pakai cookie session)
curl -b cookies.txt -o /dev/null -w "%{http_code}\n" http://laravel13-blog-dasar.test/posts/create

Guest harus mendapat 302 (redirect ke login), sementara user yang sudah login mendapat 200.

Kenapa index dan show tetap publik?

Ini keputusan desain yang wajar untuk blog — pembaca tidak perlu akun untuk sekadar membaca artikel. Yang dibatasi cuma operasi tulis (create, update, delete), bukan baca.

Selanjutnya

Sekarang siapa pun yang login bisa CRUD post — padahal idealnya hanya admin. Episode berikutnya kita tambahkan role sederhana untuk membatasi ini lebih ketat.

M
Mr Sugiarto

Developer

Bagian dari Series: Laravel 13 Dasar — Belajar Fundamental Lewat Blog Sederhana
Lihat Series Lengkap