A Complete Guide to Laravel 12 RBAC: From Setup to Landing Page
Welcome! This guide will walk you through building a complete Laravel 12 application with a robust Role-Based Access Control (RBAC) system. We’ll set up authentication and create three distinct user roles: Admin, Editor, and User. By the end, you’ll have a secure application with role-specific dashboards, a professional landing page, and the knowledge to troubleshoot common setup issues in modern Laravel.
Let’s get started.
Step 1: Set Up Your Laravel 12 Project
First, let’s create a fresh Laravel project. Open your terminal and run the following Composer command:
bashcomposer create-project --prefer-dist laravel/laravel laravel-rbac
Once the project is created, navigate into the directory:
cd laravel-rbac
Next, configure your database. Open the .env file in the root of your project and update the DB_ variables with your local database credentials.
DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=laravel_rbacDB_USERNAME=rootDB_PASSWORD=
Step 2: Add Authentication Scaffolding
Laravel makes it easy to set up login and registration systems. We’ll use the laravel/ui package with Bootstrap.
composer require laravel/uiphp artisan ui bootstrap --authnpm installnpm run dev
These commands generate all the necessary authentication views, routes, and controllers. Keep the npm run dev process running in a terminal to compile your assets as you work.
Step 3: Implement Role-Based Access Control (RBAC)
Now, let’s build the core of our RBAC system. We’ll add a role column to our users table to manage permissions.
Create the Migration
Generate a migration to add the role column:
bashphp artisan make:migration add_role_to_users_table --table=users
Open the new migration file in database/migrations/ and modify the up method to add the column. We’ll set ‘user’ as the default role.
php// ...
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('role')->default('user'); // Default role is 'user'
});
}
// ...
Run the migration to update your database schema:
php artisan migrate
Create the Role Middleware
Middleware is perfect for protecting routes. Let’s create one to check a user’s role.
bashphp artisan make:middleware RoleMiddleware
This creates app/Http/Middleware/RoleMiddleware.php. Open it and update the handle method to check if the authenticated user has the required role.
<?phpnamespace App\Http\Middleware;use Closure;use Illuminate\Http\Request;use Illuminate\Support\Facades\Auth;use Symfony\Component\HttpFoundation\Response;class RoleMiddleware{ public function handle(Request $request, Closure $next, $role): Response { if (Auth::check() && Auth::user()->role == $role) { return $next($request); } return redirect('/home')->with('error', 'You do not have permission to access this page.'); }}
Register the Middleware (The Laravel 12 Way)
In Laravel 11 and 12, middleware aliases are no longer registered in app/Http/Kernel.php. Instead, you register them in bootstrap/app.php.
Open bootstrap/app.php and add your middleware alias inside the withMiddleware() method.
php<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// Register your 'role' middleware alias here
$middleware->alias([
'role' => \App\Http\Middleware\RoleMiddleware::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
// ...
})->create();
This is a critical step. Forgetting it will cause a Target class [role] does not exist error.
Step 4: Define Role-Specific Routes
With the middleware registered, you can now protect routes in routes/web.php. We’ll create separate dashboard routes for each role.
use Illuminate\Support\Facades\Route;use App\Http\Controllers\HomeController;use App\Http\Controllers\LandingPageController;// Landing PageRoute::get('/', [LandingPageController::class, 'index']);Auth::routes();// Home redirectorRoute::get('/home', [HomeController::class, 'index'])->name('home');// Admin RoutesRoute::middleware(['auth', 'role:admin'])->group(function () { Route::get('/admin/dashboard', function () { return view('admin.dashboard'); })->name('admin.dashboard');});// Editor RoutesRoute::middleware(['auth', 'role:editor'])->group(function () { Route::get('/editor/dashboard', function () { return view('editor.dashboard'); })->name('editor.dashboard');});// User RoutesRoute::middleware(['auth', 'role:user'])->group(function () { Route::get('/user/dashboard', function () { return view('user.dashboard'); })->name('user.dashboard');});
Step 5: Set Up Controllers and Views
Modify the RegisterController
Update the RegisterController at app/Http/Controllers/Auth/RegisterController.php to ensure new users are automatically assigned the ‘user’ role.
// ... in RegisterController.phpuse App\Models\User;use Illuminate\Support\Facades\Hash;protected function create(array $data){ return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), 'role' => 'user', // Automatically assign 'user' role ]);}
Modify the HomeController
The HomeController will act as a router after login, redirecting users to the correct dashboard based on their role. Open app/Http/Controllers/HomeController.php and update the index method.
// ... in HomeController.phpuse Illuminate\Support\Facades\Auth;public function index(){ $role = Auth::user()->role; if ($role == 'admin') { return redirect()->route('admin.dashboard'); } elseif ($role == 'editor') { return redirect()->route('editor.dashboard'); } else { return redirect()->route('user.dashboard'); }}
Create the Dashboard Views
Create the following Blade files for each role’s dashboard.
Admin Dashboard (resources/views/admin/dashboard.blade.php):
@extends('layouts.app')@section('content')<div class="container"> <div class="card"> <div class="card-header">{{ __('Admin Dashboard') }}</div> <div class="card-body">Welcome, Admin! You have full control.</div> </div></div>@endsection
Editor Dashboard (resources/views/editor/dashboard.blade.php):
@extends('layouts.app')@section('content')<div class="container"> <div class="card"> <div class="card-header">{{ __('Editor Dashboard') }}</div> <div class="card-body">Welcome, Editor! You can manage content.</div> </div></div>@endsection
User Dashboard (resources/views/user/dashboard.blade.php):
@extends('layouts.app')@section('content')<div class="container"> <div class="card"> <div class="card-header">{{ __('User Dashboard') }}</div> <div class="card-body">Welcome, User! This is your personal space.</div> </div></div>@endsection
Step 6: Build a Professional Landing Page
A great application needs a welcoming landing page. Let’s create one using Tailwind CSS for modern styling.
Create the Controller
php artisan make:controller LandingPageController
Add an index method to app/Http/Controllers/LandingPageController.php:
public function index(){ return view('welcome');}
Create the Blade View
Replace the content of resources/views/welcome.blade.php with the following code. It includes a hero section, features, and a footer.
<!DOCTYPE html><html lang="{{ str_replace('_', '-', app()->getLocale()) }}"><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel RBAC Starter</title> <link rel="preconnect" href="https://fonts.bunny.net"> <link href="https://fonts.bunny.net/css?family=instrument-sans:400,500,600,700" rel="stylesheet" /> @vite(['resources/sass/app.scss', 'resources/js/app.js'])</head><body class="bg-gray-50 text-gray-800 antialiased"> <div class="relative min-h-screen flex flex-col items-center justify-center"> <!-- Header --> <header class="w-full max-w-7xl mx-auto px-6 lg:px-8 absolute top-0 pt-6"> @if (Route::has('login')) <nav class="flex items-center justify-end gap-4"> @auth <a href="{{ url('/home') }}" class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20]">Dashboard</a> @else <a href="{{ route('login') }}" class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20]">Log in</a> @if (Route::has('register')) <a href="{{ route('register') }}" class="rounded-md px-3 py-2 text-black ring-1 ring-transparent transition hover:text-black/70 focus:outline-none focus-visible:ring-[#FF2D20]">Register</a> @endif @endauth </nav> @endif </header> <!-- Main Content --> <main class="w-full max-w-7xl mx-auto px-6 lg:px-8 text-center py-20"> <h1 class="text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl">Your App with Role-Based Access</h1> <p class="mt-6 text-lg leading-8 text-gray-600">A robust starting point for your next Laravel project, complete with authentication and pre-configured user roles.</p> <div class="mt-10 flex items-center justify-center gap-x-6"> <a href="{{ route('register') }}" class="rounded-md bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500">Get Started</a> <a href="#features" class="text-sm font-semibold leading-6 text-gray-900">Learn more <span aria-hidden="true">→</span></a> </div> </main> <!-- Footer --> <footer class="w-full text-center py-8 text-sm text-gray-500"> <p>Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }})</p> </footer> </div></body></html>
Note: This landing page assumes you have Tailwind CSS installed. If you used laravel/ui bootstrap, the styling might differ. You can install Tailwind by following the official Laravel documentation.
Step 7: Testing and Final Touches
To test your roles, you’ll need to manually update a user’s role in the database.
- Register a new user (they will have the ‘user’ role).
- Use a database client like phpMyAdmin or Sequel Ace to change their
rolein theuserstable toadminoreditor. - Log in as that user. You should be redirected to the correct dashboard.
Congratulations! You now have a fully functional Laravel 12 application with authentication and a multi-tiered RBAC system. This starter project is the perfect foundation for building complex, secure web applications.

I’m Abhishek, a DevOps, SRE, DevSecOps, and Cloud expert with a passion for sharing knowledge and real-world experiences. I’ve had the opportunity to work with Cotocus and continue to contribute to multiple platforms where I share insights across different domains:
-
DevOps School – Tech blogs and tutorials
-
Holiday Landmark – Travel stories and guides
-
Stocks Mantra – Stock market strategies and tips
-
My Medic Plus – Health and fitness guidance
-
TrueReviewNow – Honest product reviews
-
Wizbrand – SEO and digital tools for businesses
I’m also exploring the fascinating world of Quantum Computing.
Best Cardiac Hospitals Near You
Discover top heart hospitals, cardiology centers & cardiac care services by city.
Advanced Heart Care • Trusted Hospitals • Expert Teams
View Best Hospitals