
Laravel 12 Custom Multi-Auth Login System: A Step-by-Step Guide
Table of Contents
Welcome to my blog, where we dive into the world of web development and explore the power of Laravel, one of the most popular PHP frameworks! Whether you're a beginner or an experienced developer, this blog is designed to help you learn, grow, and master the art of building modern, efficient, and secure web applications.
In this post, we'll walk you through creating a Custom Multi-Auth Login System in Laravel 12. This step-by-step guide will teach you how to implement separate authentication systems for different user roles (like Admin and User), define guards, create middleware, and set up role-based access control. By the end of this tutorial, you'll have a fully functional multi-auth system that you can integrate into your own projects.
Read Also: Laravel 12 AJAX CRUD Example : A Step-by-Step Guide
Step 1: Setting Up Laravel 12 Project
Start by creating a new Laravel 12 project: create one with Composer:
composer create-project --prefer-dist laravel/laravel laravel12-multi-auth
Navigate to the project directory by running the following command in your terminal
cd laravel12-multi-auth
Step 2: Database Configuration
Open the .env file and update your database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<DATABASE NAME> #example : laravel12_multi_auth
DB_USERNAME=<DATABASE USERNAME> #example : root
DB_PASSWORD=<DATABASE PASSWORD>
Ensure your database is created before proceeding.
Step 3: Creating Authentication Using Laravel UI
Install the Laravel UI package and generate authentication scaffolding:
composer require laravel/ui
php artisan ui bootstrap --auth
npm install
npm run dev
This will create login, registration, and dashboard views.
Step 4: Generating Model and Migration
In this step, we'll create a Model and Migration for the Admin authentication system. This will allow us to manage admin-specific data in the database.
-
Generate the Admin Model and Migration
Run the following Artisan command to create the Admin model and its corresponding migration file:
php artisan make:model Admin -m
-
Update the Admin Model
Open the Admin model file located at app/Models/Admin.php and update it with the following code:
namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Database\Eloquent\Model; class Admin extends Authenticatable { protected $guard = 'admin'; protected $fillable = [ 'name', 'email', 'password', ]; protected $hidden = [ 'password', 'remember_token', ]; protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; } }
-
Define the Migration Schema
Open the migration file generated earlier database/migrations/xxxx_xx_xx_create_admins_table.php and update it to define the schema for the admins table:
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(); // Auto-incrementing ID $table->string('name'); // Admin's name $table->string('email')->unique(); // Unique email $table->timestamp('email_verified_at')->nullable(); // Email verification timestamp $table->string('password'); // Password $table->rememberToken(); // Remember token for "remember me" functionality $table->timestamps(); // Created at and updated at timestamps }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('admins'); // Drop the table if migration is rolled back } };
-
Run the Migration
Execute the migration to create the admins table in your database:
php artisan migrate
Step 5: Defining Guards
In this step, we'll define guards for the Admin and User roles. Guards help Laravel differentiate between authentication systems for different user types
-
Update the User Model
Open the User model located at app/Models/User.php and specify the guard for regular users:
namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Factories\HasFactory; class User extends Authenticatable { use HasFactory, Notifiable; // Specify the guard for this model protected $guard = 'user'; }
-
Update the Admin Model
Open the Admin model located at app/Models/Admin.php and specify the guard for admin users:
namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Database\Eloquent\Factories\HasFactory; class Admin extends Authenticatable { use HasFactory; // Specify the guard for this model protected $guard = 'admin'; }
-
Update the config/auth.php File
Open the config/auth.php file and define the guards, providers, and password reset settings for both Admin and User roles.
Guards
Add the admin and user guards:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ 'driver' => 'session', 'provider' => 'admins', ], 'user' => [ 'driver' => 'session', 'provider' => 'users', ], ],
Providers
Define the providers for users and admins:
'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], 'admins' => [ 'driver' => 'eloquent', 'model' => App\Models\Admin::class, ], ],
Password Reset Settings
Configure password reset settings for both roles:
'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_reset_tokens', 'expire' => 60, 'throttle' => 60, ], 'admins' => [ 'provider' => 'admins', 'table' => 'password_reset_tokens', 'expire' => 60, 'throttle' => 60, ], ],
Step 6: Creating Middleware for Guards
In this step, we'll create middleware to enforce role-based access control for Admin and User roles.
Middleware ensures that only authenticated users with the correct role can access specific routes.
-
Generate Middleware for Admin Auth
Run the following Artisan command to create middleware for Admin authentication:
php artisan make:middleware IsAdmin
Open the generated file app/Http/Middleware/IsAdmin.php and update it with the following code:
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Symfony\Component\HttpFoundation\Response; class IsAdmin { public function handle(Request $request, Closure $next): Response { // Check if the user is authenticated as an admin if (Auth::guard('admin')->check()) { return $next($request); // Allow access } // Redirect to admin login page if not authenticated return redirect()->route('admin.login')->with('error', 'Access Denied! You are not an admin.'); } }
-
Generate Middleware for User Auth
Run the following Artisan command to create middleware for User authentication:
php artisan make:middleware IsUser
Open the generated file app/Http/Middleware/IsUser.php and update it with the following code:
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Symfony\Component\HttpFoundation\Response; class IsUser { public function handle(Request $request, Closure $next): Response { // Check if the user is authenticated as a regular user if (Auth::guard('user')->check()) { return $next($request); // Allow access } // Redirect to user login page if not authenticated return redirect()->route('login')->with('error', 'Access Denied! You are not a user.'); } }
-
Register Middleware in AppMiddleware
Create a new file app/Http/AppMiddleware.php to handle middleware logic:
namespace App\Http; use Illuminate\Foundation\Configuration\Middleware; class AppMiddleware { public function __invoke(Middleware $middleware) { // Define middleware aliases $middleware->alias([ 'isAdmin' => \App\Http\Middleware\IsAdmin::class, 'isUser' => \App\Http\Middleware\IsUser::class, ]); } }
-
Update bootstrap/app.php
Open the bootstrap/app.php file and update the withMiddleware method to register the middleware:
->withMiddleware(new App\Http\AppMiddleware())
Step 7: Setting Up Routes
In this step, we'll define routes for the Admin and User roles. This ensures that each role has its own set of routes and access control.
-
Admin Routes
Create a file routes/admin/panel.php and add the following code:
use Illuminate\Support\Facades\Route; use App\Http\Controllers\Auth\Admin\LoginController; use App\Http\Controllers\Admin\DashboardController as AdminDashboard; // Admin routes Route::prefix('admin')->name('admin.')->group(function () { // Login routes Route::get('/login', [LoginController::class, 'showAdminLoginForm'])->name('login'); Route::post('/login', [LoginController::class, 'adminLogin']); // Protected routes (only accessible by admins) Route::middleware('isAdmin')->group(function () { Route::get('/dashboard', [AdminDashboard::class, 'index'])->name('dashboard'); Route::post('/logout', [LoginController::class, 'logout'])->name('logout'); }); });
-
User Routes
Create a file routes/user/panel.php and add the following code:
use Illuminate\Support\Facades\Route; use App\Http\Controllers\User\DashboardController; // User routes Route::prefix('user')->name('user.')->group(function () { // Protected routes (only accessible by users) Route::middleware('isUser')->group(function () { Route::get('/', [DashboardController::class, 'index'])->name('dashboard'); Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard'); }); });
-
Configure Routes in bootstrap/app.php
Open the bootstrap/app.php file and update the withRouting method to include the Admin and User routes:
->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', then: function () { // Load user routes Route::middleware('web') ->group(base_path('routes/user/panel.php')); // Load admin routes Route::middleware('web') ->group(base_path('routes/admin/panel.php')); }, )
At the top of the bootstrap/app.php file, make sure to import the Route facade:
use Illuminate\Support\Facades\Route;
Step 8: Creating Controllers
In this step, we'll create controllers to handle the logic for Admin and User authentication and dashboard functionality. Controllers are essential for processing requests and returning responses.
-
Admin Login Controller
Generate the Admin Login controller using the following Artisan command:
php artisan make:controller Auth/Admin/LoginController
Open the generated file app/Http/Controllers/Auth/Admin/LoginController.php and add the following code:
namespace App\Http\Controllers\Auth\Admin; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = '/admin/dashboard'; public function __construct() { $this->middleware('guest')->except('logout'); $this->middleware('guest:admin')->except('logout'); } protected function guard(){ return Auth::guard('admin'); } public function showAdminLoginForm() { return view('admin.auth.login', ['url' => 'admin']); } public function adminLogin(Request $request) { $this->validate($request, [ 'email' => 'required|email', 'password' => 'required|min:6' ]); if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) { return redirect()->route('admin.dashboard')->with('success','You are Logged in sucessfully.'); } else { return back()->with('error','Whoops! invalid email and password.'); } } public function logout(Request $request) { auth()->guard('admin')->logout(); Session::put('success', 'You are logout sucessfully'); return redirect('/admin/login'); } }
-
Admin Dashboard Controller
Generate the Admin Dashboard controller using the following Artisan command:
php artisan make:controller Admin/DashboardController
Open the generated file app/Http/Controllers/Admin/DashboardController.php and add the following code:
namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; class DashboardController extends Controller { public function __construct() { $this->middleware('isAdmin'); } public function index(Request $request){ $data = []; return view("admin.dashboard",$data); } }
-
Update User Login Controller
Open the default LoginController located at app/Http/Controllers/Auth/LoginController.php and ensure it handles user authentication:
namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; use Illuminate\Http\Request; class LoginController extends Controller { use AuthenticatesUsers; public function __construct() { $this->middleware('guest')->except('logout'); $this->middleware('guest:user')->except('logout'); } public function login(Request $request) { $this->validate($request, [ 'email' => 'required|email', 'password' => 'required|min:6' ]); $credentials = $request->only('email', 'password'); if (Auth::guard('user')->attempt($credentials, $request->get('remember'))) { return redirect()->route('user.dashboard')->with('success','You are Logged in sucessfully.'); } else { return back()->with('error','Whoops! invalid email and password.'); } } public function logout(Request $request) { auth()->guard('user')->logout(); $request->session()->regenerateToken(); Session::put('success', 'You are logout sucessfully'); return redirect('/login'); } }
-
User Dashboard Controller
Generate the User Dashboard controller using the following Artisan command:
php artisan make:controller User/DashboardController
Open the generated file app/Http/Controllers/User/DashboardController.php and add the following code:
namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; class DashboardController extends Controller { public function index(Request $request){ $data = []; return view("user.dashboard",$data); } }
Step 9: Designing a Reusable Template Layout
In this step, we'll create reusable layout templates for the Admin and User dashboards. These layouts will include common elements like headers, footers, and navigation bars, making it easier to maintain consistency across your application.
-
Admin Layout
Generate the Admin layout view using the following Artisan command:
php artisan make:view admin.layouts.app
Open the generated file resources/views/admin/layouts/app.blade.php and update it with the following code:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="csrf-token" content="{{ csrf_token() }}"/> <title>Laravel 12 Custom Multi-Auth Login System: A Step-by-Step Guide</title> <link rel="dns-prefetch" href="//fonts.bunny.net" > <link rel="stylesheet" type="text/css" href="https://fonts.bunny.net/css?family=Nunito"> @vite(['resources/sass/app.scss', 'resources/js/app.js']) </head> <body>
@yield('content') -
User Layout
Generate the User layout view using the following Artisan command:
php artisan make:view user.layouts.app
Open the generated file resources/views/user/layouts/app.blade.php and update it with the following code:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="csrf-token" content="{{ csrf_token() }}"/> <title>Laravel 12 Custom Multi-Auth Login System: A Step-by-Step Guide</title> <link rel="dns-prefetch" href="//fonts.bunny.net" > <link rel="stylesheet" type="text/css" href="https://fonts.bunny.net/css?family=Nunito"> @vite(['resources/sass/app.scss', 'resources/js/app.js']) </head> <body>
@yield('content')
Step 10: Building Blade Views
In this step, we'll create Blade views for the Admin login, Admin dashboard, and User dashboard. These views will use the reusable layouts we designed earlier and provide the user interface for authentication and dashboard functionality.
-
Admin Login View
Generate the Admin login view using the following Artisan command:
php artisan make:view admin.auth.login
Open the generated file resources/views/admin/auth/login.blade.php and add the following code:
@extends('admin.layouts.app') @section('content') {{ __('Login') }} -
Admin Dashboard View
Generate the Admin dashboard view using the following Artisan command:
php artisan make:view admin.dashboard
Open the generated file resources/views/admin/dashboard.blade.php and add the following code:
@extends('admin.layouts.app') @section('content') {{ __('Dashboard') }}Welcome to Admin Dashboard @if (Auth::guard('admin')->user())Logged in as: {{ Auth::guard('admin')->user()->name }}
@elseNot logged in
@endif -
User Dashboard View
Generate the User dashboard view using the following Artisan command:
php artisan make:view user.dashboard
Open the generated file resources/views/user/dashboard.blade.php and add the following code:
@extends('user.layouts.app') @section('content') {{ __('Dashboard') }}Welcome to User Dashboard @if (Auth::guard('user')->user())Logged in as: {{ Auth::guard('user')->user()->name }}
@elseNot logged in
@endif
Step 11: Creating and Running Seeders
In this step, we'll create seeders to populate the database with initial data for Admin and User roles.
Seeders are useful for testing and setting up default data in your application.
-
Admin Seeder
Generate the Admin seeder using the following Artisan command:
php artisan make:seed AdminTableSeeder
Open the generated file database/seeders/AdminTableSeeder.php and add the following code:
namespace Database\Seeders; use Illuminate\Database\Seeder; use App\Models\Admin; use Illuminate\Support\Facades\Hash; class AdminTableSeeder extends Seeder { public function run() { // Create a default admin user Admin::create([ 'name' => 'Admin', 'email' => 'admin@tipinfotrove.com', 'password' => Hash::make('12345678'), // Use a secure password ]); } }
-
User Seeder
Generate the User seeder using the following Artisan command:
php artisan make:seed UserTableSeeder
Open the generated file database/seeders/UserTableSeeder.php and add the following code:
namespace Database\Seeders; use Illuminate\Database\Seeder; use App\Models\User; use Illuminate\Support\Facades\Hash; class UserTableSeeder extends Seeder { public function run() { // Create a default regular user User::create([ 'name' => 'User', 'email' => 'user@tipinfotrove.com', 'password' => Hash::make('12345678'), // Use a secure password ]); } }
-
Update the Database Seeder
Open the database/seeders/DatabaseSeeder.php file and update it to call the Admin and User seeders:
namespace Database\Seeders; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { public function run() { $this->call([ UserTableSeeder::class, AdminTableSeeder::class, ]); } }
-
Run the Seeders
Run the following commands to execute the seeders and populate the database:
php artisan db:seed --class=AdminTableSeeder php artisan db:seed --class=UserTableSeeder
Alternatively, you can run all seeders at once using:
php artisan db:seed
Step 12: Running the Application
-
Run the Project
Start the development server:
php artisan serve
-
Preview the Application
Open your web browser and navigate to the following URL to view the code preview:
http://localhost:8000Preview:
User Dashboard
Admin Dashboard
Step 13: Testing and Debugging
Once you've built your Laravel 12 Custom Multi-Auth Login System, it's time to test and debug the application to ensure everything works as expected. Testing is a critical step to identify and fix any issues before deploying your application to production. Here's how you can effectively test and debug your multi-auth system:
Test User Authentication
-
Admin Login:
- Visit the admin login page (e.g., http://localhost:8000/admin/login).
- Enter valid admin credentials (email and password) and submit the form.
- Verify that you are redirected to the admin dashboard (/admin/dashboard).
-
User Login:
- Visit the user login page (e.g., http://localhost:8000/login).
- Enter valid user credentials (email and password) and submit the form.
- Verify that you are redirected to the user dashboard (/user/dashboard).
-
Test Logout Functionality for both auth
-
Fix Tailwind CSS Not Working in Laravel 12 (Vite Setup)
If Tailwind CSS is not working in Laravel 12 and the welcome.blade.php page is not loading styles correctly, Modify your vite.config.js file to correctly include Tailwind CSS.
import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ plugins: [ laravel({ input: [ 'resources/sass/app.scss', 'resources/js/app.js', ], refresh: true, }), tailwindcss(), ], });
After making these changes, run:
php artisan config:clear npm run dev php artisan serve
Conclusion
Congratulations! You've successfully built a custom multi-auth login system in Laravel 12. This system allows you to manage multiple user roles with separate authentication and role-based access control. Keep experimenting and enhancing your Laravel skills!
Get the complete source code on GitHub: Click here to download Code
0 Comments