How To Make Multiple Authentication in Laravel 11 Breeze using Guards
In this post, you will be learning how to make a Multi Guard authentication system with Laravel Breeze in Laravel 11.
So basically, we will create a separate Login & Register page with an authentication system for Admin. So in this tutorial, we will be creating the Admin authentication system using Guard in Laravel 11.
Laravel Multiple Authentication using Guards with Example.
Step 1: Create a Laravel Project using below command
composer create-project laravel/laravel example-app
Setup and update the Database in .env file
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel11
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 to migrate all the tables into database.
php artisan migrate
Step 3: Create the Migration for Admin with the below command
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_06_7_000000_create_admins_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('admins');
}
};
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 Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use HasFactory, Notifiable;
protected $guard = 'admin';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
the changes are in this Model is extends Authenticatable and adding guard.
Step 5: Configure Authentication Guards & Providers in config/auth.php
Open "config/auth.php" file andcheck for guard and provider and update as shown below:
Guard
'guards' => [
//...
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
Provider
'providers' => [
//...
'admins' => [
'driver' => 'eloquent',
'model' => env('AUTH_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
Create Register Controller with below command:
php artisan make:controller Auth/Admin/RegisterController
Open: "app/ Http/ Controllers/ Auth/ Admin/ RegisterController.php" and paste the below code
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Controller;
use App\Models\Admin;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Illuminate\View\View;
class RegisteredUserController extends Controller
{
/**
* Display the registration view.
*/
public function create(): View
{
return view('admin.auth.register');
}
/**
* Handle an incoming registration request.
*
* @throws \Illuminate\Validation\ValidationException
*/
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', Rules\Password::defaults()],
]);
$admin = Admin::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($admin));
Auth::guard('admin')->login($admin);
return redirect(route('admin.dashboard', absolute: false));
}
}
Create Login Controller with below command:
php artisan make:controller Auth/Admin/LoginController
Now, let's create a FormRequest validation form with below command for AdminLogin (it will be used in Admin/LoginController):
php artisan make:request Auth/AdminLoginRequest
Open: "app/ Http/ Request/ Auth/ AdminLoginRequest.php" and paste the below code
<?php
namespace App\Http\Requests\Auth;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class AdminLoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
*/
public function rules(): array
{
return [
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
];
}
/**
* Attempt to authenticate the request's credentials.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate(): void
{
$this->ensureIsNotRateLimited();
if (! Auth::guard('admin')->attempt($this->only('email', 'password'), $this->boolean('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
/**
* Ensure the login request is not rate limited.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function ensureIsNotRateLimited(): void
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
/**
* Get the rate limiting throttle key for the request.
*/
public function throttleKey(): string
{
return Str::transliterate(Str::lower($this->string('email')).'|'.$this->ip());
}
}
Now, open: "app/ Http/ Controllers/ Auth/ Admin/ LoginController.php" and paste the below code
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\AdminLoginRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
class LoginController extends Controller
{
/**
* Display the login view.
*/
public function create(): View
{
return view('admin.auth.login');
}
/**
* Handle an incoming authentication request.
*/
public function store(AdminLoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(route('admin.dashboard', absolute: false));
}
/**
* Destroy an authenticated session.
*/
public function destroy(Request $request): RedirectResponse
{
Auth::guard('admin')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/admin/login');
}
}
Step 7: Create a Routes
Open web.php file ( routes/web.php ) and add the below code in it:
<?php
// ...
require __DIR__.'/admin-auth.php';
Now, let's create a admin-auth.php file inside routes folder ( routes/admin-auth.php ) and paste the below code:
<?php
use App\Http\Controllers\Admin\Auth\LoginController;
use App\Http\Controllers\Admin\Auth\RegisteredUserController;
use Illuminate\Support\Facades\Route;
Route::prefix('admin')->middleware('guest:admin')->group(function () {
Route::get('register', [RegisteredUserController::class, 'create'])->name('admin.register');
Route::post('register', [RegisteredUserController::class, 'store']);
Route::get('login', [LoginController::class, 'create'])->name('admin.login');
Route::post('login', [LoginController::class, 'store']);
});
Route::prefix('admin')->middleware('auth:admin')->group(function () {
Route::get('/dashboard', function () {
return view('admin.dashboard');
})->name('admin.dashboard');
Route::post('logout', [LoginController::class, 'destroy'])->name('admin.logout');
});
Step 8: Create the Blade files listed below:
1. login.blade.php
2. register.blade.php
3. dashboard.blade.php
Create Login Blade file in following path: "resources /views /admin /auth /login.blade.php"
<x-guest-layout>
<!-- Session Status -->
<x-auth-session-status class="mb-4" :status="session('status')" />
<h3 class="text-center mb-3">Admin Login Page</h3>
<form method="POST" action="{{ route('admin.login') }}">
@csrf
<!-- Email Address -->
<div>
<x-input-label for="email" :value="__('Email')" />
<x-text-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus autocomplete="username" />
<x-input-error :messages="$errors->get('email')" class="mt-2" />
</div>
<!-- Password -->
<div class="mt-4">
<x-input-label for="password" :value="__('Password')" />
<x-text-input id="password" class="block mt-1 w-full"
type="password"
name="password"
required autocomplete="current-password" />
<x-input-error :messages="$errors->get('password')" class="mt-2" />
</div>
<!-- Remember Me -->
<div class="block mt-4">
<label for="remember_me" class="inline-flex items-center">
<input id="remember_me" type="checkbox" class="rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500" name="remember">
<span class="ms-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
</label>
</div>
<div class="flex items-center justify-end mt-4">
@if (Route::has('password.request'))
<a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('password.request') }}">
{{ __('Forgot your password?') }}
</a>
@endif
<x-primary-button class="ms-3">
{{ __('Log in') }}
</x-primary-button>
</div>
</form>
</x-guest-layout>
Create Register Blade file in following path: "resources /views /admin /auth /register.blade.php"
<x-guest-layout>
<h3 class="text-center mb-3">Admin Register Page</h3>
<form method="POST" action="{{ route('admin.register') }}">
@csrf
<!-- Name -->
<div>
<x-input-label for="name" :value="__('Name')" />
<x-text-input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" />
<x-input-error :messages="$errors->get('name')" class="mt-2" />
</div>
<!-- Email Address -->
<div class="mt-4">
<x-input-label for="email" :value="__('Email')" />
<x-text-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autocomplete="username" />
<x-input-error :messages="$errors->get('email')" class="mt-2" />
</div>
<!-- Password -->
<div class="mt-4">
<x-input-label for="password" :value="__('Password')" />
<x-text-input id="password" class="block mt-1 w-full"
type="password"
name="password"
required autocomplete="new-password" />
<x-input-error :messages="$errors->get('password')" class="mt-2" />
</div>
<!-- Confirm Password -->
<div class="mt-4">
<x-input-label for="password_confirmation" :value="__('Confirm Password')" />
<x-text-input id="password_confirmation" class="block mt-1 w-full"
type="password"
name="password_confirmation" required autocomplete="new-password" />
<x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" />
</div>
<div class="flex items-center justify-end mt-4">
<a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('login') }}">
{{ __('Already registered?') }}
</a>
<x-primary-button class="ms-4">
{{ __('Register') }}
</x-primary-button>
</div>
</form>
</x-guest-layout>
Create Dashboard Blade file in following path: "resources /views /admin /dashboard.blade.php"
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Admin Dashboard') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900">
<h4>Admin Dashboard Page</h4>
<form method="POST" action="{{ route('admin.logout') }}">
@csrf
<x-responsive-nav-link :href="route('admin.logout')"
onclick="event.preventDefault();
this.closest('form').submit();">
{{ __('Log Out') }}
</x-responsive-nav-link>
</form>
</div>
</div>
</div>
</div>
</x-app-layout>
Let's open the app layout navigation and update the Logout code
Please search the Logout button in your Navbar and update the below code. path: "resources /views /layouts /navigation.blade.php"
<!-- Authentication -->
@if (Auth::guard('admin')->check())
<form method="POST" action="{{ route('admin.logout') }}">
@csrf
<x-dropdown-link :href="route('admin.logout')"
onclick="event.preventDefault();
this.closest('form').submit();">
{{ __('Log Out') }}
</x-dropdown-link>
</form>
@else
<form method="POST" action="{{ route('logout') }}">
@csrf
<x-dropdown-link :href="route('logout')"
onclick="event.preventDefault();
this.closest('form').submit();">
{{ __('Log Out') }}
</x-dropdown-link>
</form>
@endif
Let's serve the application with the following command:
php artisan serve
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.