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:
bashcd 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.
textDB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_rbac
DB_USERNAME=root
DB_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.
bashcomposer require laravel/ui
php artisan ui bootstrap --auth
npm install
npm 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:
bashphp 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.
php<?php
namespace 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.
phpuse Illuminate\Support\Facades\Route;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\LandingPageController;
// Landing Page
Route::get('/', [LandingPageController::class, 'index']);
Auth::routes();
// Home redirector
Route::get('/home', [HomeController::class, 'index'])->name('home');
// Admin Routes
Route::middleware(['auth', 'role:admin'])->group(function () {
Route::get('/admin/dashboard', function () {
return view('admin.dashboard');
})->name('admin.dashboard');
});
// Editor Routes
Route::middleware(['auth', 'role:editor'])->group(function () {
Route::get('/editor/dashboard', function () {
return view('editor.dashboard');
})->name('editor.dashboard');
});
// User Routes
Route::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.
php// ... in RegisterController.php
use 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.
php// ... in HomeController.php
use 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
):
xml@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
):
xml@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
):
xml@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
bashphp artisan make:controller LandingPageController
Add an index
method to app/Http/Controllers/LandingPageController.php
:
phppublic 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.
xml<!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
role
in theusers
table toadmin
oreditor
. - 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.