Kritim Yantra
May 12, 2025
In this comprehensive guide, we'll walk through creating a secure admin login system using Laravel and Livewire. This solution will include authentication, authorization, and a clean admin interface.
Laravel is a powerful PHP framework that provides elegant syntax and tools for building modern web applications. It includes built-in features for authentication, routing, sessions, and caching.
Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple, without leaving the comfort of Laravel. It allows you to write front-end code directly in your Blade templates with reactive behavior.
Together, they provide an excellent stack for building interactive admin panels with real-time features.
First, let's create a new Laravel project:
composer create-project laravel/laravel admin-panel
cd admin-panel
Next, install Livewire:
composer require livewire/livewire
Add the Livewire directives to your layout file. Create resources/views/layouts/app.blade.php
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Panel</title>
@livewireStyles
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100">
{{ $slot }}
@livewireScripts
</body>
</html>
Set up your database in the .env
file:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=admin_panel
DB_USERNAME=root
DB_PASSWORD=
Run the migrations:
php artisan migrate
We'll use Laravel's built-in User model but extend it for admin functionality. First, let's modify the default migration:
// In database/migrations/..._create_users_table.php
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->boolean('is_admin')->default(false);
$table->rememberToken();
$table->timestamps();
});
Run the migration:
php artisan migrate:fresh
Update the User model (app/Models/User.php
):
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
'is_admin',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
'is_admin' => 'boolean',
];
public function isAdmin()
{
return $this->is_admin;
}
}
Install Laravel Breeze for authentication scaffolding:
composer require laravel/breeze --dev
php artisan breeze:install
php artisan migrate
npm install && npm run dev
This will set up the basic authentication views and routes.
Create a new Livewire component for the admin login:
php artisan make:livewire Auth/AdminLogin
Update app/Http/Livewire/Auth/AdminLogin.php
:
<?php
namespace App\Http\Livewire\Auth;
use Livewire\Component;
use Illuminate\Support\Facades\Auth;
class AdminLogin extends Component
{
public $email;
public $password;
public $remember = false;
public $error;
protected $rules = [
'email' => 'required|email',
'password' => 'required',
];
public function render()
{
return view('livewire.auth.admin-login')
->layout('layouts.app');
}
public function login()
{
$this->validate();
$credentials = [
'email' => $this->email,
'password' => $this->password,
'is_admin' => true,
];
if (Auth::attempt($credentials, $this->remember)) {
return redirect()->intended('/admin/dashboard');
}
$this->error = 'Invalid credentials or you are not an admin.';
}
}
Create the view at resources/views/livewire/auth/admin-login.blade.php
:
<div class="min-h-screen flex items-center justify-center">
<div class="bg-white p-8 rounded-lg shadow-md w-full max-w-md">
<h1 class="text-2xl font-bold mb-6 text-center">Admin Login</h1>
@if($error)
<div class="mb-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded">
{{ $error }}
</div>
@endif
<form wire:submit.prevent="login">
<div class="mb-4">
<label for="email" class="block text-gray-700 mb-2">Email</label>
<input
type="email"
id="email"
wire:model="email"
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
autofocus
>
@error('email') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
</div>
<div class="mb-6">
<label for="password" class="block text-gray-700 mb-2">Password</label>
<input
type="password"
id="password"
wire:model="password"
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
>
@error('password') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
</div>
<div class="mb-6 flex items-center">
<input
type="checkbox"
id="remember"
wire:model="remember"
class="mr-2"
>
<label for="remember" class="text-gray-700">Remember me</label>
</div>
<button
type="submit"
class="w-full bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition duration-150"
>
Login
</button>
</form>
</div>
</div>
Create a Livewire component for the admin dashboard:
php artisan make:livewire Admin/Dashboard
Update app/Http/Livewire/Admin/Dashboard.php
:
<?php
namespace App\Http\Livewire\Admin;
use Livewire\Component;
class Dashboard extends Component
{
public function render()
{
return view('livewire.admin.dashboard')
->layout('layouts.app', ['title' => 'Admin Dashboard']);
}
}
Create the view at resources/views/livewire/admin/dashboard.blade.php
:
<div class="min-h-screen">
<nav class="bg-white shadow">
<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">
<div class="flex-shrink-0 flex items-center">
<h1 class="text-xl font-bold text-gray-900">Admin Panel</h1>
</div>
</div>
<div class="flex items-center">
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="text-gray-500 hover:text-gray-700 px-3 py-2 rounded-md text-sm font-medium">
Logout
</button>
</form>
</div>
</div>
</div>
</nav>
<header class="bg-white shadow">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<h2 class="text-xl font-semibold text-gray-900">
Dashboard
</h2>
</div>
</header>
<main>
<div class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
<div class="px-4 py-6 sm:px-0">
<div class="border-4 border-dashed border-gray-200 rounded-lg h-96 p-4">
<p class="text-gray-500">Welcome to your admin dashboard!</p>
<p class="mt-4 text-gray-500">You're logged in as: {{ auth()->user()->email }}</p>
</div>
</div>
</div>
</main>
</div>
Create a middleware to protect admin routes:
php artisan make:middleware AdminMiddleware
Update app/Http/Middleware/AdminMiddleware.php
:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
public function handle(Request $request, Closure $next)
{
if (!Auth::check() || !Auth::user()->isAdmin()) {
return redirect('/admin/login')->with('error', 'You do not have admin access.');
}
return $next($request);
}
}
Register the middleware in bootstrap/app.php
:
<?php
use Illuminate\Foundation\Application;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php'
)
->withMiddleware(function ($middleware) {
$middleware->alias([
'admin' => \App\Http\Middleware\AdminMiddleware::class,
]);
})
->create();
Laravel Breeze already provides logout functionality, but let's ensure it works with our admin routes.
Update routes/web.php
:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Livewire\Auth\AdminLogin;
use App\Http\Livewire\Admin\Dashboard;
Route::get('/admin/login', AdminLogin::class)->name('admin.login');
Route::get('/admin/dashboard', Dashboard::class)->name('admin.dashboard')->middleware('admin');
// Regular user routes
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__.'/auth.php';
First, create an admin user. Create a seeder:
php artisan make:seeder AdminUserSeeder
Update database/seeders/AdminUserSeeder.php
:
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class AdminUserSeeder extends Seeder
{
public function run()
{
User::create([
'name' => 'Admin User',
'email' => 'admin@example.com',
'password' => Hash::make('password'),
'is_admin' => true,
]);
}
}
Run the seeder:
php artisan db:seed --class=AdminUserSeeder
Now you can:
/admin/login
admin@example.com
and password
/admin/dashboard
directly - it should redirect if not logged inIn this tutorial, we've built a complete admin login system using Laravel and Livewire. We've covered:
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google