Multi Guard Authentication with Breeze in Laravel 10

By Ved Prakash N | Feb 13, 2024 | Laravel
Share : Whatsapp

https://www.fundaofwebit.com/post/multi-guard-authentication-with-breeze-in-laravel-10

Multi Guard Authentication with Breeze in Laravel 10


In this post, you will be learning how to make a Multi Guard authentication system with Laravel Breeze in Laravel 10.

So basically, we are going to create a separate Login & Register page with an authentication system for Admin or Teacher or Employee. So in this tutorial, we will be creating the Admin authentication system using Guard in Laravel 10.

Laravel Multi Auth using Guards with Example [Web Authentication]


Step 1: Install the Laravel Application.

Install Laravel with the following command:

composer create-project laravel/laravel example-app

Setup the Database in .env file

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


Step 2: Install the Laravel Breeze for the authentication system.

composer require laravel/breeze --dev

After successfully installing the Laravel Breeze package, run the below artisan command to install it in the application.

php artisan breeze:install blade

once breeze:install is completed, run the below 3 commands:

php artisan migrate
npm install
npm run dev


Step 3: Create the Migration for Admin as follows:

Run the below artisan command to generate admin migration file.

php artisan make:migration create_admins_table

After successfully generating the migration, let's add the fields to it as given below - path: database/ migrations/ 2024_02_13_030757_create_admins_table.php

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


Step 4: Create a Admin Model with the following command:

php artisan make:model Admin

After successfully creating the Admin model - path: app/ Models/ Admin.php. Open the Admin model and replace it with the below code:

<?php

namespace App\Models;

use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    use HasApiTokens, HasFactory;

protected $guard = 'admin';

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

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

    protected $casts = [
        'password' => 'hashed',
    ];
}


Step 5: Configure Authentication Guards & Providers

In the config/auth.php file, define multiple guards, each associated with a user model. Laravel allows you to configure different authentication drivers for each guard. For example, you can use the "web" guard for regular users with session-based authentication and the "admin" guard for administrators with session-based or token-based authentication.

So let's add Guards:

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

So let's add Providers:

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


Quick Notes:

Now, to login into the system as an admin user, we need to use the admin guard while login as shown below:

Auth::guard('admin')->attempt($request->only('email', 'password'), $request->boolean('remember'))

If we don’t pass the guard, laravel selects the default guard which is the web guard. You can change it in the config/auth.php file under the default array. and wherever you require to get the auth user data you can get it as follow:

Auth::guard('admin')->user();


Step 6: Create a Controller to Implement Authentication Logic for admins login, register and logout:

First, we will create RegisterController with the below command: 

php artisan make:controller Auth/Admin/RegisterController

This will create a controller and you will find in the path: app/ Http/ Controllers/ Auth/ Admin/ RegisterController.php and paste the below code in it:

<?php

namespace App\Http\Controllers\Auth\Admin;

use App\Models\Admin;
use Illuminate\View\View;
use Illuminate\Http\Request;
use App\Providers\RouteServiceProvider;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\RedirectResponse;

class RegisterController extends Controller
{
    public function create(): View
    {
        return view('admin.auth.register');
    }

    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.Admin::class],
            'password' => ['required', 'confirmed', 'min:8'],
        ]);

        $admin = Admin::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        Auth::guard('admin')->login($admin);

        return redirect(RouteServiceProvider::ADMIN_DASHBOARD);
    }
}


Now, let's create LoginController with the below command: 

php artisan make:controller Auth/Admin/LoginController

This will create a controller and you will find in the path: app/ Http/ Controllers/ Auth/ Admin/ LoginController.php and paste the below code in it:

<?php

namespace App\Http\Controllers\Auth\Admin;

use Illuminate\View\View;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\RedirectResponse;
use App\Providers\RouteServiceProvider;
use Illuminate\Validation\ValidationException;

class LoginController extends Controller
{
    public function create(): View
    {
        return view('admin.auth.login');
    }

    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'email' => ['required', 'string', 'lowercase', 'email', 'max:255'],
            'password' => ['required', 'string'],
        ]);

        if(! Auth::guard('admin')->attempt($request->only('email', 'password'), $request->boolean('remember')))
        {
            throw ValidationException::withMessages([
                'email' => trans('auth.failed'),
            ]);
        }

        $request->session()->regenerate();

        return redirect()->intended(RouteServiceProvider::ADMIN_DASHBOARD);
    }

    public function destroy(Request $request): RedirectResponse
    {
        Auth::guard('admin')->logout();

        $request->session()->invalidate();

        $request->session()->regenerateToken();

        return redirect('/admin/login');
    }
}



Step 7: Add a redirect path in RouteServiceProvider.php as shown below for ADMIN_DASHBOARD

Open the file from path: app/ Providers/ RouteServiceProvider.php 

class RouteServiceProvider extends ServiceProvider
{
    public const HOME = '/dashboard';
    public const ADMIN_DASHBOARD = '/admin/dashboard';
   
    ...


Step 8: Create the Routes

Route::middleware('guest:admin')->prefix('admin')->group( function () {

    Route::get('login', [App\Http\Controllers\Auth\Admin\LoginController::class, 'create'])->name('admin.login');
    Route::post('login', [App\Http\Controllers\Auth\Admin\LoginController::class, 'store']);

    Route::get('register', [App\Http\Controllers\Auth\Admin\RegisterController::class, 'create'])->name('admin.register');
    Route::post('register', [App\Http\Controllers\Auth\Admin\RegisterController::class, 'store']);

});

Route::middleware('auth:admin')->prefix('admin')->group( function () {

    Route::post('logout', [App\Http\Controllers\Auth\Admin\LoginController::class, 'destroy'])->name('admin.logout');

    Route::view('/dashboard','admin.dashboard');

});


Step 9: Create a layout named AdminLayout with the following command: 

If you already have a LAYOUT for Admin. you can SKIP this Step 9. 

php artisan make:component AdminLayout

After running this command, 2 files will be generated that is Component AdminLayout.php and component as blade file - admin-layout.blade.php

Now, open this AdminLayout Component in the path: app/ View/ Components/ AdminLayout.php and Modify the view() path as shown:

<?php

namespace App\View\Components;

use Illuminate\Contracts\View\View;
use Illuminate\View\Component;

class AdminLayout extends Component
{
    /**
     * Get the view / contents that represents the component.
     */
    public function render(): View
    {
        return view('layouts.admin');
    }
}


Now, go to the component blade file from the following path: resources/ views/ components/ admin-layout.blade.php and "RENAME" this blade file from 'admin-layout.blade.php' to 'admin.blade.php'.  Finally, let's move this admin.blade.php file from - "resources/ views/ components/ admin.blade.php"  to  "resources/ views/ layouts" folder.

So now, we have successfully created the Admin Layout. Open the admin layout blade file - path: resources/ views/ layouts/ admin.blade.php and paste the below code:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ $title ?? 'Laravel 10 Tutorial' }}</title>

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">

</head>
<body>

    <nav class="navbar navbar-expand-lg bg-body-tertiary shadow sticky-top">
        <div class="container">
            <a class="navbar-brand" href="#">Admin Navbar</a>

            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
                aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>

            <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav ms-auto mb-2 mb-lg-0">
                    <li class="nav-item">
                        <a class="nav-link active" href="{{ url('/') }}">Home</a>
                    </li>
                    @guest('admin')
                    <li class="nav-item">
                        <a class="nav-link fw-bold" href="{{ route('admin.login') }}">Login</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link fw-bold" href="{{ route('admin.register') }}">Register</a>
                    </li>
                    @else
                    <div class="dropdown">
                        <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                            {{ Auth::guard('admin')->user()->name }}
                        </button>
                        <ul class="dropdown-menu">
                            <li>
                                <form method="POST" action="{{ route('admin.logout') }}">
                                    @csrf
                                    <a
                                        class="dropdown-item" href="{{ route('admin.logout') }}"
                                        onclick="event.preventDefault();
                                        this.closest('form').submit();"
                                    >
                                        Log Out
                                    </a>
                                </form>
                            </li>
                        </ul>
                      </div>
                    @endguest
                </ul>
            </div>
        </div>
    </nav>

    <div>
        {{ $slot }}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>

    {{ $scripts ?? '' }}

</body>
</html>


Step 10: Create the Blade files as follows:

In this blade files, We are using Bootstrap CSS to design the Forms and pages.  

10.1: Create a Register blade file in the following path: resources/ views/ admin/ auth /register.blade.php

<x-admin-layout>

    <div class="container mt-5">
        <div class="row justify-content-center">
            <div class="col-md-5">
                <div class="card shadow">
                    <div class="card-header text-center bg-primary">
                        <h4 class="text-white">Register</h4>
                    </div>
                    <div class="card-body">
                        <form method="POST" action="{{ route('admin.register') }}">
                            @csrf

                            <div class="mb-3">
                                <label for="name">Name</label>
                                <input type="text" name="name" value="{{ old('name') }}" class="form-control" />
                                @error('name') <span class="text-danger">{{ $message }}</span> @enderror
                            </div>
                            <div class="mb-3">
                                <label for="email">Email</label>
                                <input type="email" name="email" value="{{ old('email') }}" class="form-control" />
                                @error('email') <span class="text-danger">{{ $message }}</span> @enderror
                            </div>
                            <div class="mb-3">
                                <label for="password">Password</label>
                                <input type="password" name="password" class="form-control" />
                                @error('password') <span class="text-danger">{{ $message }}</span> @enderror
                            </div>
                            <div class="mb-3">
                                <label for="password_confirmation">Confirm Password</label>
                                <input type="password" name="password_confirmation" class="form-control" />
                                @error('password_confirmation') <span class="text-danger">{{ $message }}</span> @enderror
                            </div>
                            <div class="mb-3 text-center">
                                <button type="submit" class="btn btn-primary w-100">Register</button>
                                <div class="mt-3">
                                    <a href="{{ route('admin.login') }}">Already registerd?</a>
                                </div>
                            </div>

                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

</x-admin-layout>


10.2: Create a Login blade file in the following path: resources/ views/ admin/ auth /login.blade.php

<x-admin-layout>

    <div class="container mt-5">
        <div class="row justify-content-center">
            <div class="col-md-4">
                <div class="card shadow">
                    <div class="card-header text-center bg-primary">
                        <h4 class="text-white">Login</h4>
                    </div>
                    <div class="card-body">
                        <form method="POST" action="{{ route('admin.login') }}">
                            @csrf

                            <div class="mb-3">
                                <label for="email">Email</label>
                                <input type="email" name="email" value="{{ old('email') }}" class="form-control" />
                                @error('email') <span class="text-danger">{{ $message }}</span> @enderror
                            </div>
                            <div class="mb-3">
                                <label for="password">Password</label>
                                <input type="password" name="password" class="form-control" />
                                @error('password') <span class="text-danger">{{ $message }}</span> @enderror
                            </div>
                            <div class="mb-3">
                                <label for="remember_me">
                                    <input type="checkbox" name="remember" id="remember_me" />
                                    Remember Me
                                </label>
                            </div>
                            <div class="mb-3 text-center">
                                <button type="submit" class="btn btn-primary w-100">Login</button>
                                <div class="mt-3">
                                    <a href="{{ route('admin.register') }}">Don't have account? register now</a>
                                </div>
                            </div>

                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

</x-admin-layout>


10.3: Create a Dashboard blade file in the following path: resources/ views/ admin/ dashboard.blade.php

<x-admin-layout>

    <div class="container mt-5">
        <div class="row">
            <h1>Welcome to Admin Dashboard</h1>
        </div>
    </div>

</x-admin-layout>


Let's serve the application and open the login page on the browser as:

Login: http://localhost:8000/admin/login

Register: http://localhost:8000/admin/register


That's it. We have successfully created a new auth guard as admin.

I hope this helps you. Thanks for reading.