Cara Menerapkan Multi Auth di Laravel 12
  • Admin
  • 18 Jul 2025
  • Laravel

Cara Menerapkan Multi Auth di Laravel 12

Halo teman-teman developer! ๐Ÿ‘‹

Kalau kamu sedang bikin aplikasi Laravel 12 dan ingin memisahkan login antara Admin dan User biasa, berarti kamu butuh yang namanya Multi Auth.

Multi Auth memungkinkan dua sistem login yang berbeda dalam satu aplikasi — misalnya, admin punya halaman login sendiri di /admin/login, sementara user biasa tetap login di /login.

Laravel 12 sudah sangat fleksibel untuk ini, apalagi kalau pakai Laravel Breeze untuk setup autentikasi dasarnya. Kali ini kita akan bahas dari awal banget — mulai dari membuat project, setup database, model Admin, sampai sistem login lengkap dengan middleware dan seeder.

๐Ÿš€ 1. Buat Project Laravel Baru

Buka terminal dan jalankan perintah berikut:

composer create-project laravel/laravel multi-auth-app
cd multi-auth-app

Pastikan project berjalan lancar:

php artisan serve

Buka di browser: http://localhost:8000 — kalau muncul halaman Laravel, berarti sukses ๐ŸŽ‰

๐Ÿงฉ 2. Setup Database & .env

Buka file .env dan ubah pengaturan database-nya seperti berikut:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=multi_auth
DB_USERNAME=root
DB_PASSWORD=

Buat database di phpMyAdmin atau terminal:

CREATE DATABASE multi_auth;

๐Ÿ” 3. Install Laravel Breeze

composer require laravel/breeze --dev
php artisan breeze:install blade
npm install && npm run dev
php artisan migrate

Setelah ini, kamu sudah bisa login dan register user biasa di /login dan /register.

๐Ÿ‘จ‍๐Ÿ’ผ 4. Buat Model & Tabel Admin

php artisan make:model Admin -m

Edit migration di database/migrations/<tanggal>_create_admins_table.php:

Schema::create('admins', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

Lalu isi model app/Models/Admin.php dengan kode berikut:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class Admin extends Authenticatable
{
    use Notifiable;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];
}

Setelah itu, jalankan migrasi:

php artisan migrate

โš™๏ธ 5. Konfigurasi Multi Auth di config/auth.php

Tambahkan konfigurasi untuk guard dan provider admin:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Models\Admin::class,
    ],
],

๐Ÿงญ 6. Buat Controller Login Admin

php artisan make:controller Admin/AuthController

Isi app/Http/Controllers/Admin/AuthController.php:

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    public function showLoginForm()
    {
        // Jika admin sudah login, arahkan langsung ke dashboard
        if (Auth::guard('admin')->check()) {
            return redirect()->route('admin.dashboard');
        }

        return view('admin.login');
    }

    public function login(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (Auth::guard('admin')->attempt($credentials)) {
            return redirect()->intended('/admin/dashboard');
        }

        return back()->withErrors(['email' => 'Email atau password salah']);
    }

    public function logout()
    {
        Auth::guard('admin')->logout();
        return redirect('/admin/login');
    }
}

๐Ÿงฑ 7. Buat Middleware Admin

php artisan make:middleware RedirectIfNotAdmin

Edit app/Http/Middleware/RedirectIfNotAdmin.php:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfNotAdmin
{
    public function handle($request, Closure $next)
    {
        if (!Auth::guard('admin')->check()) {
            return redirect()->route('admin.login');
        }
        return $next($request);
    }
}

๐Ÿ›ฃ๏ธ 8. Tambahkan Route untuk Admin

use App\Http\Controllers\Admin\AuthController;
use App\Http\Middleware\RedirectIfNotAdmin;

Route::prefix('admin')->name('admin.')->group(function () {
    // Login & Logout
    Route::get('/login', [AuthController::class, 'showLoginForm'])->name('login');
    Route::post('/login', [AuthController::class, 'login']);
    Route::post('/logout', [AuthController::class, 'logout'])->name('logout');

    // Dashboard dilindungi middleware
    Route::get('/dashboard', function () {
        return view('admin.dashboard');
    })->middleware(RedirectIfNotAdmin::class)->name('dashboard');
});

๐ŸŽจ 9. Buat View untuk Admin

Buat file resources/views/admin/login.blade.php:

<!DOCTYPE html>
<html lang="id">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Admin</title>

    <script src="https://cdn.tailwindcss.com"></script>

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">

    <style>
        body {
            font-family: 'Poppins', sans-serif;
        }
    </style>
</head>

<body class="bg-gradient-to-br from-blue-50 via-white to-purple-50 min-h-screen flex items-center justify-center p-4">

    <div class="bg-white w-full max-w-md p-8 md:p-10 rounded-2xl shadow-2xl transition-all duration-300">

        <div class="flex justify-center mb-4">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-blue-600" fill="none" viewBox="0 0 24 24"
                stroke="currentColor" stroke-width="2">
                <path stroke-linecap="round" stroke-linejoin="round"
                    d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
            </svg>
        </div>

        <h2 class="text-3xl font-bold text-gray-900 text-center mb-2">Login Admin</h2>
        <p class="text-gray-500 text-center mb-8">Selamat datang kembali! Silakan masuk.</p>

        @if ($errors->any())
            <div class="bg-red-50 border border-red-300 text-red-800 rounded-xl p-3 text-sm mb-6" role="alert">
                <p>{{ $errors->first() }}</p>
            </div>
        @endif

        <form method="POST" action="{{ route('admin.login') }}" class="space-y-5">
            @csrf

            <div>
                <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email</label>
                <input type="email" name="email" id="email" placeholder="admin@email.com" required
                    autocomplete="email"
                    class="w-full px-4 py-3 border border-gray-300 rounded-xl shadow-sm bg-gray-50 
                           focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
                           transition-all"
                    value="{{ old('email') }}">
            </div>

            <div>
                <label for="password" class="block text-sm font-medium text-gray-700 mb-1">Password</label>
                <input type="password" name="password" id="password" placeholder="••••••••" required
                    autocomplete="current-password"
                    class="w-full px-4 py-3 border border-gray-300 rounded-xl shadow-sm bg-gray-50
                           focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent
                           transition-all">
            </div>

            <div>
                <button type="submit"
                    class="w-full bg-blue-600 text-white py-3 px-4 rounded-xl font-bold shadow-lg 
                           hover:bg-blue-700 
                           focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
                           transform hover:-translate-y-0.5 transition-all duration-300 ease-in-out">
                    Login
                </button>
            </div>
        </form>

    </div>

</body>

</html>

Buat file resources/views/admin/dashboard.blade.php

<!DOCTYPE html>
<html lang="id">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Admin Dashboard</title>

    <script src="https://cdn.tailwindcss.com"></script>

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">

    <style>
        body {
            font-family: 'Poppins', sans-serif;
        }
    </style>
</head>

<body class="bg-gray-100 min-h-screen">

    <nav class="bg-white shadow-md">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="flex justify-between h-16">
                <div class="flex items-center">
                    <span class="text-2xl font-bold text-blue-600">Admin Panel</span>
                </div>

                <div class="flex items-center">
                    <a href="{{ route('admin.logout') }}"
                        onclick="event.preventDefault(); document.getElementById('logout-form').submit();"
                        class="bg-red-500 text-white px-4 py-2 rounded-lg text-sm font-medium
                              hover:bg-red-600 transition-colors duration-300
                              focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2">
                        Logout
                    </a>

                    <form id="logout-form" action="{{ route('admin.logout') }}" method="POST" class="hidden">
                        @csrf
                    </form>
                </div>
            </div>
        </div>
    </nav>

    <main>
        <div class="max-w-7xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
            <div class="bg-white rounded-2xl shadow-xl p-8 md:p-12 text-center">

                <div class="flex justify-center mb-4">
                    <svg xmlns="http://www.w3.org/2000/svg" class="h-20 w-20 text-green-500" fill="none"
                        viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                        <path stroke-linecap="round" stroke-linejoin="round"
                            d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                </div>

                <h1 class="text-4xl font-bold text-gray-900 mb-2">
                    Selamat datang, Admin!
                </h1>
                <p class="text-lg text-gray-600">
                    Anda telah berhasil login ke panel admin.
                </p>

            </div>
        </div>
    </main>

</body>

</html>

๐Ÿ’พ 10. Buat Seeder untuk Testing

php artisan make:seeder UserAndAdminSeeder

Edit database/seeders/UserAndAdminSeeder.php:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
use App\Models\User;
use App\Models\Admin;

class UserAndAdminSeeder extends Seeder
{
    public function run(): void
    {
        // User biasa
        User::updateOrCreate(
            ['email' => 'user@example.com'],
            [
                'name' => 'User Biasa',
                'password' => Hash::make('password'),
            ]
        );

        // Admin
        Admin::updateOrCreate(
            ['email' => 'admin@example.com'],
            [
                'name' => 'Admin Super',
                'password' => Hash::make('password'),
            ]
        );

        $this->command->info('โœ… User dan Admin berhasil dibuat!');
    }
}

Edit database/seeders/DatabaseSeeder.php agar seeder otomatis dijalankan:

public function run(): void
{
    $this->call(UserAndAdminSeeder::class);
}

Jalankan seeder:

php artisan db:seed

๐Ÿงช 11. Testing Login

Gunakan akun berikut untuk mencoba:

Role Email Password URL Login
User user@example.com password /login
Admin admin@example.com password /admin/login

๐ŸŽฏ 12. Hasil Akhir

Sekarang kamu punya dua sistem login berbeda dengan session terpisah:

Role Guard Model Login Path
User web App\Models\User /login
Admin admin App\Models\Admin /admin/login

โœ… Penutup

Dengan langkah-langkah di atas, kamu sudah punya sistem Multi Auth Laravel 12 yang lengkap:

  • โœ”๏ธ Login dan register user biasa (Laravel Breeze)
  • โœ”๏ธ Login khusus admin dengan guard sendiri
  • โœ”๏ธ Middleware untuk proteksi halaman admin
  • โœ”๏ธ Redirect otomatis jika admin sudah login
  • โœ”๏ธ Seeder untuk testing cepat

Sekarang kamu bisa lanjut menambahkan fitur role-based access, CRUD untuk admin, dan dashboard keren sesuai kebutuhanmu. Selamat ngoding! ๐Ÿš€๐Ÿ”ฅ

Artikel Terkait

Baca Artikel Lainnya