Creating an Admin Account in Laravel 11 with Breeze: A Step-by-Step Guide


7 min read 11-11-2024
Creating an Admin Account in Laravel 11 with Breeze: A Step-by-Step Guide

Welcome, fellow developers, to this comprehensive guide on creating an admin account in Laravel 11 using the powerful Breeze authentication system. Breeze, a robust and streamlined authentication scaffolding package, provides a fantastic foundation for crafting user management and authorization features in your Laravel applications.

This guide will take you through a step-by-step process, covering everything from initial setup to final implementation. By the end of this journey, you'll have a solid understanding of how to create a dedicated admin account and manage user roles within your Laravel 11 project.

Setting Up a Laravel 11 Project with Breeze

First things first, we need to establish a new Laravel 11 project and integrate Breeze. Let's follow these simple steps:

  1. Create a new Laravel project:

    laravel new my-laravel-app
    
  2. Navigate into the project directory:

    cd my-laravel-app
    
  3. Install Breeze:

    composer require laravel/breeze --dev
    
  4. Install the Breeze scaffolding:

    php artisan breeze:install
    
  5. Start the development server:

    php artisan serve
    

Now, you have a fresh Laravel 11 project equipped with Breeze. Let's move on to customizing Breeze to accommodate our admin account needs.

Creating an Admin Model and Migrations

In our quest to build an effective admin system, we need distinct models for users and admins. We'll create a new model for admins and generate the necessary database migrations:

  1. Create the Admin model:

    php artisan make:model Admin -m
    
  2. Add isAdmin attribute to the Admin model:

    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    
    class Admin extends Model
    {
        use HasFactory;
    
        protected $fillable = [
            'name',
            'email',
            'password',
            'is_admin'
        ];
    
        // ...
    }
    
  3. Update the User model:

    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Foundation\Auth\User as Authenticatable;
    use Illuminate\Notifications\Notifiable;
    use Laravel\Sanctum\HasApiTokens;
    
    class User extends Authenticatable
    {
        use HasApiTokens, HasFactory, Notifiable;
    
        /**
         * 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',
        ];
    
        /**
         * The attributes that should be cast.
         *
         * @var array<string, string>
         */
        protected $casts = [
            'email_verified_at' => 'datetime',
        ];
    }
    
  4. Modify the users migration (database/migrations/YYYY_MM_DD_HHMMSS_create_users_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.
         *
         * @return void
         */
        public function up()
        {
            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); // Add is_admin column
                $table->rememberToken();
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('users');
        }
    };
    
  5. Run the database migrations:

    php artisan migrate
    

Now, our database is set up with separate tables for users and admins, ready to store our user data, including the crucial is_admin flag.

Creating an Admin Controller and Route

To manage our admin account, we need a dedicated controller and route. Here's how we'll implement them:

  1. Create an AdminController:

    php artisan make:controller AdminController
    
  2. Define routes in routes/web.php:

    <?php
    
    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\AdminController;
    
    Route::get('/admin', [AdminController::class, 'index'])->name('admin.index');
    
  3. Implement logic in the AdminController:

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class AdminController extends Controller
    {
        /**
         * Display the admin dashboard.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            return view('admin.index');
        }
    }
    
  4. Create the admin dashboard view (resources/views/admin/index.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 Dashboard</title>
    </head>
    <body>
        <h1>Welcome to the Admin Dashboard</h1>
    </body>
    </html>
    

Now, we have a route (/admin) that will direct to our admin dashboard. We'll build upon this foundation as we proceed.

Creating the Admin Account

Finally, the moment we've been waiting for – creating our admin account! We'll use the seeder functionality to add the admin user to our database.

  1. Create a database seeder:

    php artisan make:seeder AdminSeeder
    
  2. Implement the seeder logic (database/seeders/AdminSeeder.php):

    <?php
    
    namespace Database\Seeders;
    
    use Illuminate\Database\Console\Seeds\WithoutModelEvents;
    use Illuminate\Database\Seeder;
    use App\Models\Admin;
    
    class AdminSeeder extends Seeder
    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run()
        {
            Admin::create([
                'name' => 'Admin User',
                'email' => '[email protected]',
                'password' => bcrypt('password'),
                'is_admin' => true,
            ]);
        }
    }
    
  3. Register the seeder in database/seeders/DatabaseSeeder.php:

    <?php
    
    namespace Database\Seeders;
    
    use Illuminate\Database\Console\Seeds\WithoutModelEvents;
    use Illuminate\Database\Seeder;
    
    class DatabaseSeeder extends Seeder
    {
        /**
         * Seed the application's database.
         *
         * @return void
         */
        public function run()
        {
            // \App\Models\User::factory(10)->create();
            $this->call([
                AdminSeeder::class,
            ]);
        }
    }
    
  4. Run the database seeder:

    php artisan db:seed
    

Congratulations! You have successfully created an admin account in your Laravel 11 application.

Implementing Authorization

Now, let's ensure that only admins can access the admin dashboard. We'll implement authorization rules using the auth middleware and custom middleware.

  1. Update the AdminController:

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    
    class AdminController extends Controller
    {
        /**
         * Display the admin dashboard.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            return view('admin.index');
        }
    }
    
  2. Create a custom middleware (app/Http/Middleware/IsAdmin.php):

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Http\Request;
    
    class IsAdmin
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
         * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
         */
        public function handle(Request $request, Closure $next)
        {
            if (auth()->check() && auth()->user()->is_admin) {
                return $next($request);
            }
    
            return redirect('/'); // Or a custom unauthorized page
        }
    }
    
  3. Register the middleware in app/Http/Kernel.php:

    <?php
    
    namespace App\Http\Kernel;
    
    use Illuminate\Foundation\Http\Kernel as HttpKernel;
    
    class Kernel extends HttpKernel
    {
        /**
         * The application's global HTTP middleware stack.
         *
         * These middleware are run during every request to your application.
         *
         * @var array
         */
        protected $middleware = [
            \App\Http\Middleware\TrustProxies::class,
            \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
            \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
            \App\Http\Middleware\TrimStrings::class,
            \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        ];
    
        /**
         * The application's route middleware groups.
         *
         * @var array
         */
        protected $middlewareGroups = [
            'web' => [
                \App\Http\Middleware\EncryptCookies::class,
                \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
                \Illuminate\Session\Middleware\StartSession::class,
                \Illuminate\Session\Middleware\AuthenticateSession::class,
                \Illuminate\View\Middleware\ShareErrorsFromSession::class,
                \App\Http\Middleware\VerifyCsrfToken::class,
                \Illuminate\Routing\Middleware\SubstituteBindings::class,
            ],
    
            'api' => [
                'throttle:api',
                \Illuminate\Routing\Middleware\SubstituteBindings::class,
            ],
        ];
    
        /**
         * The application's route middleware.
         *
         * These middleware may be assigned to groups or used individually.
         *
         * @var array
         */
        protected $routeMiddleware = [
            'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
            'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
            'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
            'cache.headers' => \Illuminate\Http\Middleware\CacheResponse::class,
            'can' => \Illuminate\Auth\Middleware\Authorize::class,
            'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
            'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
            'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
            'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
            'isAdmin' => \App\Http\Middleware\IsAdmin::class, // Register the custom middleware
        ];
    }
    
  4. Apply the middleware to the admin route:

    <?php
    
    use Illuminate\Support\Facades\Route;
    use App\Http\Controllers\AdminController;
    
    Route::middleware(['auth', 'isAdmin'])->group(function () {
        Route::get('/admin', [AdminController::class, 'index'])->name('admin.index');
    });
    

Now, only users with the is_admin flag set to true will be granted access to the /admin route.

Handling User Login

Let's dive into handling user login, ensuring our admin user can authenticate successfully. We'll leverage Breeze's built-in login functionality, making the process seamless.

  1. Visit the login page (/login):

    http://localhost:8000/login
    
  2. Enter the admin's credentials:

  3. Click on the "Login" button.

Upon successful login, you'll be redirected to the admin dashboard (/admin), confirming that our authorization rules are working perfectly.

Conclusion

By following this comprehensive guide, you've gained the expertise to create a robust admin account in your Laravel 11 application using Breeze. You've learned how to set up a dedicated admin model, create migrations, implement a custom controller, and leverage authorization rules to restrict access to your admin dashboard.

Now, you have a solid foundation to expand your admin functionality by adding more features, like user management, role-based access, and advanced dashboard functionalities. Go forth, build your dream admin system, and keep your Laravel applications secure and efficient!

FAQs

Q: What if I need to create multiple admin accounts?

A: Simply modify your AdminSeeder to create multiple admin users with different email addresses and passwords.

Q: Can I customize the admin dashboard view further?

A: Absolutely! You can add more elements, widgets, charts, and functionalities to your admin dashboard view to create a comprehensive and tailored experience for your admins.

Q: How can I add different roles for admins?

A: You can create an AdminRole model, associate roles with admins, and implement role-based access control to manage permissions effectively.

Q: Can I use Breeze's built-in registration functionality for admins?

A: You can modify the registration logic to create admin accounts directly. However, it's recommended to use a seeder for initial admin creation for better security and control.

Q: What are some security best practices when working with admin accounts?

A: Always use strong passwords, implement two-factor authentication, and use a robust authorization system to prevent unauthorized access to sensitive data.