LessonsBuild a Blog → Part 4

Authentication & Admin Setup

Laravel
⏱ 20 min read🏗️ ProjectNot completed

We already installed Laravel Breeze in Lesson 1. Now we'll customize it for our blog and set up the admin panel layout.

Run Auth Migrations

Terminal
php artisan migrate

# Create admin user via seeder
php artisan db:seed

Add isAdmin to Users

Terminal
php artisan make:migration add_is_admin_to_users_table
Migration
<?php
public function up(): void
{
    Schema::table('users', function (Blueprint $table) {
        $table->boolean('is_admin')->default(false)->after('email');
    });
}
app/Models/User.php — Add method
<?php
// Add to User model
protected $fillable = ['name', 'email', 'password', 'is_admin'];

public function isAdmin(): bool
{
    return $this->is_admin === true;
}

public function posts()
{
    return $this->hasMany(Post::class);
}

public function comments()
{
    return $this->hasMany(Comment::class);
}

Admin Middleware

Terminal
php artisan make:middleware AdminMiddleware
app/Http/Middleware/AdminMiddleware.php
<?php
class AdminMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        if (!auth()->check() || !auth()->user()->isAdmin()) {
            abort(403, 'Access denied. Admin only.');
        }
        return $next($request);
    }
}

Admin Layout

resources/views/layouts/admin.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Admin — @yield('title', 'Dashboard')</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100">

<!-- Sidebar -->
<div class="flex h-screen">
    <aside class="w-64 bg-gray-900 text-white flex flex-col">
        <div class="p-6 text-xl font-bold border-b border-gray-700">
            📝 Blog Admin
        </div>
        <nav class="flex-1 p-4 space-y-2">
            <a href="/admin/dashboard" class="flex items-center gap-3 p-3 rounded hover:bg-gray-700">
                📊 Dashboard
            </a>
            <a href="/admin/posts" class="flex items-center gap-3 p-3 rounded hover:bg-gray-700">
                📄 Posts
            </a>
            <a href="/admin/categories" class="flex items-center gap-3 p-3 rounded hover:bg-gray-700">
                🏷️ Categories
            </a>
            <a href="/admin/comments" class="flex items-center gap-3 p-3 rounded hover:bg-gray-700">
                💬 Comments
            </a>
        </nav>
        <div class="p-4 border-t border-gray-700">
            <p class="text-sm text-gray-400">{{ auth()->user()->name }}</p>
            <form method="POST" action="/logout">
                @csrf
                <button class="text-sm text-red-400 hover:text-red-300">Logout</button>
            </form>
        </div>
    </aside>

    <!-- Main content -->
    <main class="flex-1 overflow-auto">
        <header class="bg-white shadow px-6 py-4">
            <h1 class="text-xl font-semibold">@yield('title', 'Dashboard')</h1>
        </header>
        <div class="p-6">
            @if(session('success'))
                <div class="bg-green-100 text-green-800 p-3 rounded mb-4">
                    {{ session('success') }}
                </div>
            @endif
            @yield('content')
        </div>
    </main>
</div>
</body>
</html>

Admin Routes

routes/web.php
<?php
use App\Http\Controllers\Admin\PostController as AdminPostController;
use App\Http\Controllers\Admin\CategoryController;
use App\Http\Controllers\Admin\CommentController;

// Admin routes — requires auth + admin
Route::prefix('admin')
    ->middleware(['auth', 'admin'])
    ->name('admin.')
    ->group(function () {
        Route::get('/dashboard', fn() => view('admin.dashboard'))->name('dashboard');
        Route::resource('posts', AdminPostController::class);
        Route::resource('categories', CategoryController::class);
        Route::resource('comments', CommentController::class)->only(['index', 'update', 'destroy']);
    });

// Register middleware alias in bootstrap/app.php
// ->withMiddleware(function (Middleware $middleware) {
//     $middleware->alias(['admin' => AdminMiddleware::class]);
// })
💡
Always protect admin routes with TWO middleware! Both auth (must be logged in) AND admin (must be admin). Just auth alone would let any registered user access the admin panel.
← Previous Next Lesson →
💡

Stuck? Need help?

Review the previous lessons or check the Laravel documentation.

Laravel Docs →