[{"data":1,"prerenderedAt":95},["ShallowReactive",2],{"\u002Fposts\u002Flogin-dan-implementasi-middleware-at?{\"username\":\"irezabdullah\"}":3},{"success":4,"message":5,"data":6},true,"Post retrieved successfully",{"post":7,"seriesInfo":25,"seriesItems":28,"seoDescription":94},{"id":8,"title":9,"slug":10,"body":11,"cover_image_path":12,"view_count":13,"part_number":14,"created_at":15,"updated_at":16,"category":17,"author":20},64,"Login Dan Implementasi Middleware","login-dan-implementasi-middleware-at","## **Materi Lengkap: Implementasi Login Manual dengan Laravel (Session + Middleware Auth)**\n\n### **1. Tujuan Pembelajaran**\n\nSetelah menyelesaikan materi ini, peserta diharapkan mampu:\n\n1.  Memahami konsep autentikasi berbasis **session** di Laravel.\n2.  Membuat sistem login dan logout dengan controller khusus.\n3.  Merancang **routing group** yang dilindungi middleware.\n4.  Menerapkan **middleware `auth`** untuk membatasi akses ke halaman tertentu.\n5.  Menghubungkan sistem login dengan fitur yang sudah ada (contoh: manajemen produk).\n\n---\n\n### **2. Gambaran Umum Alur Autentikasi**\n\nSebelum terjun ke kode, mari kita pahami alur yang akan kita bangun. Ini adalah \"cerita\" dari sistem login kita:\n\n1.  Pengguna yang belum login mencoba mengakses halaman produk (`\u002Fproducts`).\n2.  Middleware `auth` akan menangkap permintaan itu, melihat bahwa tidak ada session login, lalu **mengalihkan (redirect)** pengguna ke halaman login (`\u002Flogin`).\n3.  Di halaman login, pengguna mengisi email dan password, lalu menekan tombol submit.\n4.  Data kredensial (email & password) dikirim ke server untuk **divalidasi** dan **dicocokkan** dengan data di tabel `users`.\n5.  Jika cocok (**authentication successful**), Laravel akan membuat **session login** untuk pengguna tersebut. Pengguna kemudian diarahkan ke halaman yang awalnya ingin dia tuju (`\u002Fproducts`).\n6.  Kini, ketika pengguna mengakses `\u002Fproducts` lagi, middleware `auth` akan **memeriksa session** yang valid dan mengizinkan akses.\n7.  Saat pengguna memilih logout, session tersebut akan **dihancurkan**, dan pengguna dikembalikan ke halaman login.\n\nDengan memahami cerita ini, kode yang kita tulis nanti akan lebih bermakna.\n\n---\n\n### **3. Persiapan: Database dan Tabel Users**\n\nLaravel sudah menyediakan migration untuk tabel `users` secara default. Pastikan Anda telah menjalankan migrasi untuk membuat tabelnya di database.\n\n```bash\nphp artisan migrate\n```\n\nTabel `users` ini memiliki kolom-kolom penting seperti `id`, `name`, `email`, `password` (yang disimpan dalam bentuk terenkripsi\u002Fhash), dan `remember_token`. Kita akan menggunakan `email` dan `password` untuk proses login.\n\n---\n\n### **4. Membangun Sistem Login: Controller dan View**\n\nLangkah pertama adalah membuat **Controller** yang menangani logika login dan logout. Kita akan beri nama `AuthController`.\n\n```bash\nphp artisan make:controller AuthController\n```\n\n**File: `app\u002FHttp\u002FControllers\u002FAuthController.php`**\n\n```php\n\u003C?php\n\nnamespace App\\Http\\Controllers;\n\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Facades\\Auth;\n\nclass AuthController extends Controller\n{\n    \u002F**\n     * Menampilkan halaman form login.\n     *\u002F\n    public function showLoginForm()\n    {\n        \u002F\u002F Mengembalikan view 'auth.login'\n        return view('auth.login');\n    }\n\n    \u002F**\n     * Memproses data login yang dikirim dari form.\n     *\u002F\n    public function login(Request $request)\n    {\n        \u002F\u002F 1. Validasi input form\n        $credentials = $request->validate([\n            'email'    => 'required|email',\n            'password' => 'required|min:6',\n        ]);\n\n        \u002F\u002F 2. Attempt Login: Mencocokkan kredensial dengan database\n        if (Auth::attempt($credentials)) {\n            \u002F\u002F 3. Regenerasi Session (untuk keamanan)\n            $request->session()->regenerate();\n            \u002F\u002F 4. Redirect ke URL yang dimaksud sebelumnya, atau ke halaman default ('\u002Fproducts')\n            return redirect()->intended('\u002Fproducts');\n        }\n\n        \u002F\u002F 5. Jika attempt gagal, kembali ke halaman login dengan pesan error\n        return back()->withErrors([\n            'email' => 'Email atau password yang dimasukkan salah.',\n        ]);\n    }\n\n    \u002F**\n     * Memproses permintaan logout.\n     *\u002F\n    public function logout(Request $request)\n    {\n        \u002F\u002F 1. Logout user (menghapus session auth)\n        Auth::logout();\n        \u002F\u002F 2. Invalidasi session saat ini\n        $request->session()->invalidate();\n        \u002F\u002F 3. Regenerasi CSRF token (untuk keamanan)\n        $request->session()->regenerateToken();\n        \u002F\u002F 4. Redirect ke halaman login\n        return redirect('\u002Flogin');\n    }\n}\n```\n\n**Penjelasan Kode Controller:**\n-   Fungsi `attempt()` dari Facade `Auth` adalah inti dari login. Ia akan mengenkripsi password inputan, mencocokkannya dengan hash di database, dan secara otomatis menginisiasi session jika berhasil.\n-   `redirect()->intended()` adalah fitur cerdas Laravel. Ia akan mengingat URL yang ingin diakses pengguna sebelum di-intercept middleware, sehingga setelah login, pengguna langsung dibawa ke tujuan awalnya.\n-   Proses logout harus menghancurkan session sepenuhnya (`invalidate()`) dan membuat token baru (`regenerateToken()`) untuk mencegah serangan session fixation.\n\n**Selanjutnya, kita buat view untuk halaman login.** Kita akan menggunakan Bootstrap untuk styling yang cepat dan rapi.\n\n**File: `resources\u002Fviews\u002Fauth\u002Flogin.blade.php`**\n\n```html\n\u003C!DOCTYPE html>\n\u003Chtml lang=\"id\">\n\u003Chead>\n    \u003Cmeta charset=\"UTF-8\">\n    \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    \u003Ctitle>Halaman Login\u003C\u002Ftitle>\n    \u003C!-- Menghubungkan CSS Bootstrap 5 -->\n    \u003Clink href=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Fbootstrap@5.3.0-alpha1\u002Fdist\u002Fcss\u002Fbootstrap.min.css\" rel=\"stylesheet\">\n\u003C\u002Fhead>\n\u003Cbody class=\"bg-light d-flex align-items-center\" style=\"min-height: 100vh;\">\n    \u003Cdiv class=\"container\">\n        \u003Cdiv class=\"row justify-content-center\">\n            \u003Cdiv class=\"col-md-5\">\n                \u003Cdiv class=\"card shadow\">\n                    \u003Cdiv class=\"card-header bg-primary text-white text-center py-3\">\n                        \u003Ch4>Login ke Sistem\u003C\u002Fh4>\n                    \u003C\u002Fdiv>\n                    \u003Cdiv class=\"card-body p-4\">\n\n                        \u003C!-- Menampilkan pesan error jika validasi\u002Flogin gagal -->\n                        @if($errors->any())\n                        \u003Cdiv class=\"alert alert-danger alert-dismissible fade show\" role=\"alert\">\n                            {{ $errors->first() }}\n                            \u003Cbutton type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\">\u003C\u002Fbutton>\n                        \u003C\u002Fdiv>\n                        @endif\n\n                        \u003Cform action=\"{{ route('login') }}\" method=\"POST\">\n                            @csrf \u003C!-- Token CSRF Wajib untuk keamanan form Laravel -->\n\n                            \u003Cdiv class=\"mb-3\">\n                                \u003Clabel for=\"email\" class=\"form-label\">Alamat Email\u003C\u002Flabel>\n                                \u003Cinput type=\"email\"\n                                       class=\"form-control @error('email') is-invalid @enderror\"\n                                       id=\"email\"\n                                       name=\"email\"\n                                       value=\"{{ old('email') }}\"\n                                       placeholder=\"nama@contoh.com\"\n                                       required>\n                            \u003C\u002Fdiv>\n\n                            \u003Cdiv class=\"mb-4\">\n                                \u003Clabel for=\"password\" class=\"form-label\">Password\u003C\u002Flabel>\n                                \u003Cinput type=\"password\"\n                                       class=\"form-control @error('password') is-invalid @enderror\"\n                                       id=\"password\"\n                                       name=\"password\"\n                                       placeholder=\"Masukkan password\"\n                                       required>\n                            \u003C\u002Fdiv>\n\n                            \u003Cdiv class=\"d-grid\">\n                                \u003Cbutton type=\"submit\" class=\"btn btn-primary btn-lg\">Masuk\u003C\u002Fbutton>\n                            \u003C\u002Fdiv>\n                        \u003C\u002Fform>\n\n                    \u003C\u002Fdiv>\n                    \u003Cdiv class=\"card-footer text-center text-muted py-3\">\n                        \u003Csmall>Demo Sistem Login Laravel\u003C\u002Fsmall>\n                    \u003C\u002Fdiv>\n                \u003C\u002Fdiv>\n            \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003C!-- Menghubungkan JavaScript Bootstrap -->\n    \u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Fbootstrap@5.3.0-alpha1\u002Fdist\u002Fjs\u002Fbootstrap.bundle.min.js\">\u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n```\n\n---\n\n### **5. Menghubungkan Semuanya: Routing**\n\nRouting adalah penghubung antara URL, Controller, dan Middleware. Kita akan atur rute untuk publik (login) dan privat (yang dilindungi).\n\n**File: `routes\u002Fweb.php`**\n\n```php\n\u003C?php\n\nuse Illuminate\\Support\\Facades\\Route;\nuse App\\Http\\Controllers\\AuthController;\nuse App\\Http\\Controllers\\ProductController; \u002F\u002F Asumsi kita punya controller untuk produk\n\n\u002F\u002F --- ROUTE PUBLIK YANG SUDAH ADA SEBELUMNYA (TANPA MIDDLEWARE) ---\nRoute::get('\u002F', [HomeController::class, 'home']);\nRoute::get('\u002Fabout', [HomeController::class, 'about']);\nRoute::get('\u002Fcontact', [HomeController::class, 'contact']);\nRoute::get('\u002Ftentang-aplikasi', [HomeController::class, 'tentang_aplikasi']);\n\n\u002F\u002F --- ROUTE PUBLIK (TANPA MIDDLEWARE) ---\n\u002F\u002F Hanya pengguna belum login yang bisa akses\nRoute::get('\u002Flogin', [AuthController::class, 'showLoginForm'])->name('login');\nRoute::post('\u002Flogin', [AuthController::class, 'login']);\nRoute::post('\u002Flogout', [AuthController::class, 'logout'])->name('logout');\n\n\u002F\u002F --- ROUTE PRIVAT (DILINDUNGI MIDDLEWARE 'auth') ---\n\u002F\u002F Hanya pengguna yang sudah login yang bisa akses\nRoute::middleware(['auth'])->group(function () {\n    \u002F\u002F Semua route di dalam grup ini otomatis terlindungi\n\n    \u002F\u002F Contoh: Route untuk manajemen produk\n    Route::get('\u002Fproducts', [ProductController::class, 'index'])->name('products.index');\n    Route::get('\u002Fproducts\u002Fcreate', [ProductController::class, 'create'])->name('products.create');\n    Route::post('\u002Fproducts', [ProductController::class, 'store'])->name('products.store');\n    Route::get('\u002Fproducts\u002F{product}\u002Fedit', [ProductController::class, 'edit'])->name('products.edit');\n    Route::put('\u002Fproducts\u002F{product}', [ProductController::class, 'update'])->name('products.update');\n    Route::delete('\u002Fproducts\u002F{product}', [ProductController::class, 'destroy'])->name('products.destroy');\n\n    \u002F\u002F Contoh route lain yang perlu login\n    Route::get('\u002Fdashboard', function () {\n        return view('dashboard');\n    })->name('dashboard');\n});\n```\n\n**Mengapa route `login` dan `logout` berada di luar grup middleware `auth`?**\nKarena jika mereka dilindungi, pengguna yang belum login tidak akan bisa mengakses halaman login sama sekali—dan akan terjebak dalam loop redirect.\n\n---\n\n### **6. Middleware Auth: Sang Penjaga Gerbang**\n\n![](https:\u002F\u002Fbwaplatformbucket.sgp1.cdn.digitaloceanspaces.com\u002Fassets\u002Fthumbnail_tips\u002Fthumbnail-tips-mengenal-fitur-middleware-keamanan-dalam-framework-laravel-Untitled%20(2).png)\nSource: [buildwithangga.com](https:\u002F\u002Fbuildwithangga.com)\n\nIni adalah bagian kunci dari materi kita. **Middleware `auth`** adalah penjaga yang berdiri di depan route privat kita. Cara kerjanya sederhana namun kuat:\n\n1.  **Intercept:** Setiap kali ada request masuk ke route di dalam grupnya, middleware `auth` dijalankan terlebih dahulu.\n2.  **Cek Session:** Middleware ini memeriksa, \"Apakah request ini memiliki session login yang valid?\"\n3.  **Keputusan:**\n    -   **Jika YA:** Request diteruskan ke controller tujuan (misal, `ProductController`).\n    -   **Jika TIDAK:** Request dibelokkan (`redirect`) ke route bernama `'login'`. Laravel secara otomatis menambahkan parameter `?next=` yang berisi URL yang gagal diakses.\n\nKita tidak perlu menulis kode middleware ini karena sudah disediakan oleh Laravel. Kita hanya perlu **menerapkannya** dengan benar pada route, seperti yang telah dilakukan di atas.\n\n---\n\n### **7. Menyiapkan Data Pengguna (Seeder)**\n\nUntuk keperluan pengembangan dan testing, kita perlu membuat data user contoh. Kita buat sebuah **Seeder**.\n\n```bash\nphp artisan make:seeder UserSeeder\n```\n\n**File: `database\u002Fseeders\u002FUserSeeder.php`**\n\n```php\n\u003C?php\n\nnamespace Database\\Seeders;\n\nuse App\\Models\\User;\nuse Illuminate\\Database\\Seeder;\nuse Illuminate\\Support\\Facades\\Hash;\n\nclass UserSeeder extends Seeder\n{\n    public function run()\n    {\n        \u002F\u002F Hapus data lama jika ada (optional)\n        User::truncate();\n\n        \u002F\u002F Buat user admin contoh\n        User::create([\n            'name' => 'Administrator',\n            'email' => 'admin@demo.app',\n            'password' => Hash::make('password123'), \u002F\u002F Password di-hash\n        ]);\n\n        \u002F\u002F Bisa ditambahkan user lain di sini\n        User::create([\n            'name' => 'User Biasa',\n            'email' => 'user@demo.app',\n            'password' => Hash::make('rahasia456'),\n        ]);\n\n        $this->command->info('Sample user created successfully!');\n    }\n}\n```\n\nJalankan seeder ini untuk menambahkan user ke database:\n\n```bash\nphp artisan db:seed --class=UserSeeder\n```\n\nSekarang Anda bisa login dengan email `admin@demo.app` dan password `password123`.\n\n---\n\nOke, kita integrasikan materi **Menu Dinamis Berdasarkan Status Login** ke dalam materi yang sama. Saya akan tambahkan bagian ini setelah middleware auth, dengan penjelasan yang ringkas namun komprehensif.\n\n---\n\n**Lanjutan: Integrasi Menu Navbar Dinamis**\n\n### **8. Implementasi Menu Dinamis Berdasarkan Status Login**\n\nSetelah sistem login dan middleware berjalan, langkah logis berikutnya adalah menyesuaikan **tampilan navbar** berdasarkan apakah pengguna sudah login atau belum. Ini penting untuk UX yang baik dan keamanan.\n\nKita akan modifikasi layout utama (biasanya `resources\u002Fviews\u002Flayouts\u002Fmain.blade.php`)\n> Harap di perhatikan, untuk nama file layouts bisa saja berbeda beda tergantung pada project masing masing!.\n\nuntuk memiliki dua kondisi:\n1. **Menu untuk Pengguna Belum Login:** Menampilkan link Login.\n2. **Menu untuk Pengguna Sudah Login:** Menampilkan link Dashboard\u002FProduk, nama user, dan tombol Logout.\n\n**File: `resources\u002Fviews\u002Flayouts\u002Fmain.blade.php` (Revisi)**\n\n```html\n\u003C!DOCTYPE html>\n\u003Chtml lang=\"id\">\n\n\u003Chead>\n    \u003Cmeta charset=\"UTF-8\">\n    \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    \u003Ctitle>@yield('title', 'CRUD Produk')\u003C\u002Ftitle>\n    \u003Clink href=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Fbootstrap@5.3.3\u002Fdist\u002Fcss\u002Fbootstrap.min.css\" rel=\"stylesheet\">\n\u003C\u002Fhead>\n\n\u003Cbody>\n    \u003C!-- Navbar -->\n    \u003Cnav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n        \u003Cdiv class=\"container\">\n            \u003Ca href=\"\u002F\" class=\"navbar-brand\">CRUD Produk\u003C\u002Fa>\n\n            \u003Cbutton class=\"navbar-toggler\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#navbarNav\">\n                \u003Cspan class=\"navbar-toggler-icon\">\u003C\u002Fspan>\n            \u003C\u002Fbutton>\n\n            \u003Cdiv class=\"collapse navbar-collapse\" id=\"navbarNav\">\n                \u003C!-- Menu Kiri (Selalu Tampil) -->\n                \u003Cul class=\"navbar-nav me-auto\">\n                    \u003Cli class=\"nav-item\">\n                        \u003Ca href=\"\u002F\" class=\"nav-link {{ request()->is('\u002F') ? 'active' : '' }}\">Home\u003C\u002Fa>\n                    \u003C\u002Fli>\n                    \u003Cli class=\"nav-item\">\n                        \u003Ca href=\"\u002Fabout\" class=\"nav-link {{ request()->is('about') ? 'active' : '' }}\">About\u003C\u002Fa>\n                    \u003C\u002Fli>\n                \u003C\u002Ful>\n\n                \u003C!-- Menu Kanan (Kondisional) -->\n                \u003Cul class=\"navbar-nav\">\n\n                    \u003C!-- Menu yang hanya tampil jika user SUDAH login -->\n                    @auth\n                    \u003C!-- Menu untuk user yang SUDAH login -->\n                        \u003Cli class=\"nav-item\">\n                            \u003Ca href=\"{{ url('\u002Fdashboard') }}\"\n                                class=\"nav-link {{ request()->is('dashboard') ? 'active' : '' }}\">\n                                Dashboard\n                            \u003C\u002Fa>\n                        \u003C\u002Fli>\n                        \u003Cli class=\"nav-item\">\n                            \u003Ca href=\"{{ route('products.index') }}\"\n                                class=\"nav-link {{ request()->is('products*') ? 'active' : '' }}\">\n                                Produk\n                            \u003C\u002Fa>\n                        \u003C\u002Fli>\n                        \n                        \u003Cli class=\"nav-item dropdown\">\n                            \u003Ca class=\"nav-link dropdown-toggle\" href=\"#\" role=\"button\" data-bs-toggle=\"dropdown\">\n                                {{ Auth::user()->name }} \u003C!-- Menampilkan nama user -->\n                            \u003C\u002Fa>\n                            \u003Cul class=\"dropdown-menu dropdown-menu-end\">\n                                \u003Cli>\u003Ca class=\"dropdown-item\" href=\"{{ url('\u002Fdashboard') }}\">Dashboard\u003C\u002Fa>\u003C\u002Fli>\n                                \u003Cli>\n                                    \u003Chr class=\"dropdown-divider\">\n                                \u003C\u002Fli>\n                                \u003C!-- Form Logout -->\n                                \u003Cli>\n                                    \u003Cform method=\"POST\" action=\"{{ route('logout') }}\">\n                                        @csrf\n                                        \u003Cbutton type=\"submit\" class=\"dropdown-item text-danger\">Logout\u003C\u002Fbutton>\n                                    \u003C\u002Fform>\n                                \u003C\u002Fli>\n                            \u003C\u002Ful>\n                        \u003C\u002Fli>\n                    @else\n                        \u003C!-- Menu untuk user yang BELUM login -->\n                        \u003Cli class=\"nav-item\">\n                            \u003Ca href=\"{{ route('login') }}\" class=\"nav-link\">Login\u003C\u002Fa>\n                        \u003C\u002Fli>\n                    @endauth\n                \u003C\u002Ful>\n            \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n    \u003C\u002Fnav>\n\n    \u003C!-- Konten Utama -->\n    \u003Cdiv class=\"container mt-4\">\n        @yield('content')\n    \u003C\u002Fdiv>\n\n    \u003C!-- Script Bootstrap -->\n    \u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Fbootstrap@5.3.3\u002Fdist\u002Fjs\u002Fbootstrap.bundle.min.js\">\u003C\u002Fscript>\n\n    \u003C!-- Script Tambahan per Halaman -->\n    @stack('scripts')\n\u003C\u002Fbody>\n\n\u003C\u002Fhtml>\n```\n\n### **Penjelasan Kode Navbar Dinamis:**\n\n1. **Blade Directives `@auth` dan `@endauth`:**\nDirektif ini adalah cara **paling sederhana** untuk mengecek status login.Kode di dalamnya hanya akan ditampilkan jika user **sudah terautentikasi**.\n\t\t\n \n2. **Blade Directives `@guest` dan `@endguest`:**\n      Alternatif untuk `@auth`, khusus untuk pengguna yang **belum login**.\n      Dalam kode di atas, saya menggunakan `@else` dari `@auth` untuk efisiensi.\n \n3. **Menampilkan Data User:**\n    `{{ Auth::user()->name }}` menampilkan nama user yang sedang login.\n    `Auth::user()` mengembalikan object model User, jadi kita bisa akses semua kolom seperti `email`, `id`, dll.\n \n4. **Form Logout di Dropdown:**\n    Logout **harus menggunakan form POST** karena tindakan ini merubah state aplikasi.\n    Form kecil ini mengirimkan request ke route `logout` dengan token CSRF.\n \n5. **Highlight Menu Aktif:**\n    `{{ request()->is('products*') ? 'active' : '' }}` menambahkan class `active` jika URL saat ini berada di path `products` atau turunannya.\n    Memberikan visual feedback yang baik untuk user.\n \n### **Adaptasi View Lainnya:**\n\nSetiap view yang menggunakan layout ini (misal `products\u002Findex.blade.php`), cukup diawali dengan:\n\n```blade\n@extends('layouts.app')\n\n@section('title', 'Daftar Produk')\n\n@section('content')\n    \u003C!-- Konten halaman produk di sini -->\n@endsection\n```\n\n### **Rute Dashboard:**\n\nPastikan Anda menambahkan rute untuk dashboard di dalam grup middleware auth:\n\n```php\n\u002F\u002F Di dalam Route::middleware(['auth'])->group(function () { ... });\nRoute::get('\u002Fdashboard', function () {\n    return view('dashboard'); \u002F\u002F Buat file resources\u002Fviews\u002Fdashboard.blade.php\n})->name('dashboard');\n```\n\n### **Keuntungan Implementasi Ini:**\n\n1. **User Experience Lebih Baik:** Pengguna langsung tahu status login mereka.\n2. **Keamanan:** Menu terproteksi tidak ditampilkan ke pengguna anonim.\n3. **Konsistensi:** Semua halaman menggunakan navbar yang sama dengan logika kondisional.\n4. **Mudah Dikembangkan:** Cukup bungkus menu dengan `@auth` \u002F `@guest` untuk kontrol tampilan.\n\n### **Testing Navbar Dinamis:**\n\n1. **Akses homepage tanpa login:** Hanya tampil menu Home, About, dan Login.\n2. **Login dengan akun admin:** Menu Produk muncul, nama user tampil di dropdown dengan opsi Logout.\n3. **Klik Logout:** Kembali ke state pertama.\n\n---\n\n### **9. Kesimpulan**\n\nDengan integrasi navbar dinamis ini, sistem login kita sudah **komplit dari backend hingga frontend**. Pengguna mendapatkan pengalaman yang mulus dan aman.\n\n![](https:\u002F\u002Fcdn.rezweb.my.id\u002Fmedia\u002F16d9326e-9b49-4a71-a4e8-3faab5e70a61.webp)\n\n![](https:\u002F\u002Fcdn.rezweb.my.id\u002Fmedia\u002F5a2144da-1738-4c44-b068-e776965f611b.webp)\n\n**Rangkuman yang telah kita bangun:**\n1. ✅ Sistem Login Manual dengan Controller dan Session\n2. ✅ Middleware Auth sebagai Penjaga Route\n3. ✅ Navbar Dinamis Berdasarkan Status Login\n4. ✅ Form Logout yang Aman\n\n---\n\n##### **Ringkasan Struktur Folder Proyek Laravel 12 (Setelah Implementasi Login + Navbar)**\n\n```\n📁 laravel-12-project\u002F\n│\n├── 📁 app\u002F\n│   ├── 📁 Http\u002F\n│   │   └── 📁 Controllers\u002F\n│   │       ├── AuthController.php         # Controller login\u002Flogout (BARU)\n│   │       ├── ProductController.php      # Controller produk (sudah ada)\n│   │       └── Controller.php\n│   │\n│   ├── 📁 Models\u002F\n│   │   ├── User.php                       # Model User (default)\n│   │   └── Product.php                    # Model Produk (jika ada)\n│   │\n│   └── ...\n│\n├── 📁 bootstrap\u002F\n│   └── app.php                           # Tempat definisi middleware\n│\n├── 📁 database\u002F\n│   ├── 📁 migrations\u002F\n│   │   ├── 2014_10_12_000000_create_users_table.php\n│   │   ├── ..._create_products_table.php  # Migration produk (jika ada)\n│   │   └── ...\n│   │\n│   ├── 📁 seeders\u002F\n│   │   ├── DatabaseSeeder.php\n│   │   └── UserSeeder.php                 # Seeder user (BARU)\n│   │\n│   └── ...\n│\n├── 📁 resources\u002F\n│   ├── 📁 views\u002F\n│   │   ├── 📁 layouts\u002F\n│   │   │   └── app.blade.php              # Layout utama (SUDAH DIUPDATE)\n│   │   │\n│   │   ├── 📁 auth\u002F                       # Folder baru untuk auth views\n│   │   │   └── login.blade.php            # View login (BARU)\n│   │   │\n│   │   ├── 📁 products\u002F                   # View produk (sudah ada)\n│   │   │   ├── index.blade.php\n│   │   │   ├── create.blade.php\n│   │   │   └── ...\n│   │   │\n│   │   └── dashboard.blade.php            # View dashboard (BARU, opsional)\n│   │\n│   └── ...\n│\n├── 📁 routes\u002F\n│   └── web.php                            # SUDAH DIUPDATE dengan routing auth\n│\n├── .env\n├── composer.json\n└── ...\n```","https:\u002F\u002Fcdn.rezweb.my.id\u002Fposts\u002FtwEM4NyAd1OZPXEl8YrVyeEVbr5tMjtoMzjefj65.jpg",2574,12,"2025-12-21T09:02:01+07:00","2026-09-07T11:59:36+07:00",{"name":18,"slug":19},"LARAVEL","laravel",{"id":21,"name":22,"username":23,"avatar":24},1,"Irez Abdullah","irezabdullah","https:\u002F\u002Fcdn.rezweb.my.id\u002Favatars\u002Fd139726e-348f-4dab-95c6-bb87e2ad125e.jpeg",{"name":26,"slug":27},"Belajar Laravel dari Nol (Praktikum Web Framework) – Ringkas & Praktis","belajar-laravel-dari-nol-praktikum-web-framework-ringkas-praktis",[29,33,38,43,48,53,58,63,68,73,78,83,84,89],{"id":30,"slug":31,"title":32,"part_number":21},48,"pengenalan-web-framework-instalasi-laravel","Pengenalan Web Framework & Instalasi Laravel",{"id":34,"slug":35,"title":36,"part_number":37},49,"struktur-folder-routing-dasar","Struktur Folder & Routing Dasar",2,{"id":39,"slug":40,"title":41,"part_number":42},50,"blade-template-layouting-dengan-bootstrap-5-dmwo","Blade Template & Layouting dengan Bootstrap 5",3,{"id":44,"slug":45,"title":46,"part_number":47},51,"database-migration-qbsa","Database & Migration",4,{"id":49,"slug":50,"title":51,"part_number":52},52,"model-seeder","Model & Seeder",5,{"id":54,"slug":55,"title":56,"part_number":57},53,"controller-read-data-menampilkan-produk","Controller & Read Data (Menampilkan Produk)",6,{"id":59,"slug":60,"title":61,"part_number":62},54,"form-tambah-produk-create","Form Tambah Produk (Create)",7,{"id":64,"slug":65,"title":66,"part_number":67},55,"edit-update-produk","Edit & Update Produk",8,{"id":69,"slug":70,"title":71,"part_number":72},56,"hapus-produk-validasi-form","Hapus Produk & Validasi Form",9,{"id":74,"slug":75,"title":76,"part_number":77},63,"upload-file-gambar-dan-validasi-cpw3","Upload File (Gambar) dan Validasi",10,{"id":79,"slug":80,"title":81,"part_number":82},62,"menampilkan-grafik-stok-produk","Menampilkan Grafik Stok Produk",11,{"id":8,"slug":10,"title":9,"part_number":14},{"id":85,"slug":86,"title":87,"part_number":88},61,"membuat-dashboard-admin-dengan-statistik-dan-grafik","Membuat Dashboard Admin dengan Statistik dan Grafik",13,{"id":90,"slug":91,"title":92,"part_number":93},65,"teknik-debugging-di-laravel","Teknik Debugging di Laravel",15,"Materi Lengkap: Implementasi Login Manual dengan Laravel (Session + Middleware Auth) Tujuan Pembelajaran Setelah menyelesaikan materi ini, peserta diharapkan ma...",1788757404230]