Laravel 12 Multi-Auth System: Implementing Separate Admin and User Tables
In this blog post, we'll walk through creating a login system in Laravel 12 that supports both admin and user roles using separate database tables. This approach is useful when you need distinct authentication logic or different sets of permissions for admins and regular users. By the end, you'll have a fully functional login system with separate login forms and protected routes for each role.
Prerequisites
- Laravel 12 installed on your system.
- A basic understanding of PHP and Laravel concepts like models, controllers, and routes.
- A database (e.g., MySQL) set up and configured in your Laravel project.
If you're new to Laravel, don’t worry—I’ll explain each step in detail.
Step 1: Set Up a New Laravel 12 Project
Create a new Laravel project using Composer:
composer create-project laravel/laravel blog-login-system "12.*"
Then navigate into your project directory:
cd blog-login-system
Step 2: Configure the Database
Create a new database in your MySQL server (e.g., blog_login_db). Then, update the .env file with your database credentials:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=blog_login_db
DB_USERNAME=root
DB_PASSWORD=
Replace root and the empty password with your actual database username and password.
Step 3: Create Models and Migrations for User and Admin
Laravel comes with a User model and migration by default. We’ll use this for regular users and create a separate Admin model and migration for admins.
3.1. Update the User Migration (if necessary)
The default users table migration is located in database/migrations/xxxx_xx_xx_xxxxxx_create_users_table.php. It should include fields like id, name, email, password, and timestamps.
3.2. Create the Admin Model and Migration
Run the following command to create the Admin model and its migration:
php artisan make:model Admin -m
This generates two files:
app/Models/Admin.phpdatabase/migrations/xxxx_xx_xx_xxxxxx_create_admins_table.php
Update the admins migration to define the table structure:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAdminsTable extends Migration
{
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('admins');
}
}
3.3. Run the Migrations
Run the migrations to create the users and admins tables:
php artisan migrate
Step 4: Set Up Authentication for Users
We’ll manually set up authentication for users using Laravel’s built-in features.
4.1. Create the User Login Controller
Create a LoginController for users in app/Http/Controllers/Auth/LoginController.php:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
4.2. Create the User Login View
Create the login view for users at resources/views/auth/login.blade.php:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
4.3. Define User Authentication Routes
In routes/web.php, add the following routes for user authentication:
use App\Http\Controllers\Auth\LoginController;
Route::get('login', [LoginController::class, 'showLoginForm'])->name('login');
Route::post('login', [LoginController::class, 'login']);
Route::post('logout', [LoginController::class, 'logout'])->name('logout');
Step 5: Set Up Authentication for Admins
To handle admin authentication separately, we’ll create a new guard and a login controller for admins.
5.1. Configure Authentication Guards
Open config/auth.php and update the guards and providers sections:
'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,
],
],
5.2. Create the Admin Login Controller
Create app/Http/Controllers/Auth/AdminLoginController.php:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminLoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/admin/dashboard';
public function __construct()
{
$this->middleware('guest:admin')->except('logout');
}
public function showLoginForm()
{
return view('auth.admin-login');
}
protected function guard()
{
return Auth::guard('admin');
}
public function logout(Request $request)
{
Auth::guard('admin')->logout();
return redirect('/admin/login');
}
}
5.3. Create the Admin Login View
Create resources/views/auth/admin-login.blade.php with a similar form to the user login:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Admin Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('admin.login') }}">
@csrf
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
5.4. Define Admin Authentication Routes
Add the following routes in routes/web.php:
use App\Http\Controllers\Auth\AdminLoginController;
Route::get('admin/login', [AdminLoginController::class, 'showLoginForm'])->name('admin.login');
Route::post('admin/login', [AdminLoginController::class, 'login']);
Route::post('admin/logout', [AdminLoginController::class, 'logout'])->name('admin.logout');
Step 6: Create Protected Routes for Users and Admins
We’ll create simple dashboard views for both users and admins, protected by their respective authentication guards.
6.1. User Dashboard
Create app/Http/Controllers/HomeController.php:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function index()
{
return view('home');
}
}
Create resources/views/home.blade.php:
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Welcome, User!</h1>
<form action="{{ route('logout') }}" method="POST">
@csrf
<button type="submit" class="btn btn-danger">Logout</button>
</form>
</div>
@endsection
6.2. Admin Dashboard
Create app/Http/Controllers/AdminController.php:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AdminController extends Controller
{
public function dashboard()
{
return view('admin.dashboard');
}
}
Create resources/views/admin/dashboard.blade.php:
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Welcome, Admin!</h1>
<form action="{{ route('admin.logout') }}" method="POST">
@csrf
<button type="submit" class="btn btn-danger">Logout</button>
</form>
</div>
@endsection
6.3. Protect Routes with Middleware
In routes/web.php, use middleware to protect the dashboards:
// User routes
Route::middleware(['auth'])->group(function () {
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
});
// Admin routes
Route::middleware(['auth:admin'])->group(function () {
Route::get('/admin/dashboard', [App\Http\Controllers\AdminController::class, 'dashboard'])->name('admin.dashboard');
});
Step 7: Test the Login Systems
To test, you’ll need to create sample users and admins.
7.1. Create Sample Users and Admins
Use Laravel Tinker to add records:
php artisan tinker
Then run:
App\Models\User::create(['name' => 'User', 'email' => 'user@example.com', 'password' => bcrypt('password')]);
App\Models\Admin::create(['name' => 'Admin', 'email' => 'admin@example.com', 'password' => bcrypt('password')]);
7.2. Test User Login
Visit /login, enter user@example.com and password, and you should be redirected to /home.
7.3. Test Admin Login
Visit /admin/login, enter admin@example.com and password, and you should be redirected to /admin/dashboard.
7.4. Test Access Control
Try accessing /admin/dashboard without logging in as an admin; you should be redirected to /admin/login. Similarly, accessing /home without a user login should redirect to /login.
Conclusion
You’ve successfully set up a Laravel 12 application with separate login systems for admins and users using distinct database tables and authentication guards. This approach keeps the authentication logic clean and scalable for applications requiring role-based access.
Additional Tips
- Customization: Add more fields to the users or admins tables (e.g., role, status) for finer control.
- Middleware: For complex permissions, consider using middleware or packages like Spatie Laravel Permission.
- Security: Always use hashed passwords (bcrypt) and validate user input to prevent security vulnerabilities.
If you have questions or encounter issues, feel free to leave a comment. Happy coding with Laravel!
Projects to explore next
Source-code projects from the KritiMyantra catalogue. Check each project's details before buying.
Flask Authentication System (Free Version) - Kritim Yantra
🛠 Features✔ Google & GitHub Authentication✔ User Registration & Login✔ Profile/Dashboard Access✔ Secure & Mi...
Flask Blog CMS with Admin Dashboard — Python Source Code
A Flask-based blogging website with a built-in admin dashboard. Manage articles, images, categories, tags and featured p...
Laravel 12 + ReactJS Starter Kit: Add Multi-Language Support (Arabic, English, Spanish) with Blog CRUD
🚀 Installation & Setup Download & Extract Get the ZIP from kritimyantra.com and extract it. Includes preconfigu...
Comments
Sign in to join the discussion.