Kritim Yantra
Jun 12, 2025
Ever felt like a bouncer at a VIP club, manually checking user IDs for every page? 😅 Let’s automate that! In this guide, you’ll learn how to build a sleek access control system using Laravel 12 and Livewire—no advanced skills needed.
Imagine your app as an office building:
Without clear roles? Chaos. With Laravel 12 + Livewire? Smooth, dynamic control.
Before diving in:
composer create-project laravel/laravel my-app
composer require livewire/livewire
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
First, seed your database with default roles and permissions:
Create a seeder:
php artisan make:seeder RolePermissionSeeder
Populate database/seeders/RolePermissionSeeder.php
:
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
public function run() {
// Create permissions
$permissions = [
'create-post', 'edit-post', 'delete-post', 'view-dashboard'
];
foreach ($permissions as $permission) {
Permission::create(['name' => $permission]);
}
// Create roles
$admin = Role::create(['name' => 'admin']);
$editor = Role::create(['name' => 'editor']);
// Assign permissions to roles
$admin->givePermissionTo(Permission::all());
$editor->givePermissionTo(['create-post', 'edit-post']);
}
Run with: php artisan db:seed --class=RolePermissionSeeder
Build a Livewire component to assign roles:
Generate the component:
php artisan make:livewire RoleManager
Update app/Livewire/RoleManager.php
:
use App\Models\User;
use Spatie\Permission\Models\Role;
public $users;
public $roles;
public $selectedRole = []; // Stores user_id => role
public function mount() {
$this->users = User::with('roles')->get();
$this->roles = Role::all();
}
public function updateRole($userId) {
$user = User::find($userId);
$user->syncRoles($this->selectedRole[$userId]);
session()->flash('message', 'Role updated!');
}
Design the view (resources/views/livewire/role-manager.blade.php
):
<div class="space-y-4">
@foreach($users as $user)
<div class="flex items-center gap-4 p-4 bg-white shadow rounded">
<span class="font-bold">{{ $user->name }}</span>
<select wire:model="selectedRole.{{ $user->id }}"
wire:change="updateRole({{ $user->id }})">
@foreach($roles as $role)
<option value="{{ $role->name }}"
{{ $user->hasRole($role->name) ? 'selected' : '' }}>
{{ ucfirst($role->name) }}
</option>
@endforeach
</select>
@if(session('message') && array_key_first($this->selectedRole) == $user->id)
<span class="text-green-500">✓ Saved!</span>
@endif
</div>
@endforeach
</div>
routes/web.php
)use App\Http\Controllers\DashboardController;
use Spatie\Permission\Middlewares\PermissionMiddleware;
// Only users with 'view-dashboard' permission can access
Route::get('/dashboard', DashboardController::class)
->middleware(['auth', PermissionMiddleware::using('view-dashboard')]);
Add to Livewire components (e.g., app/Livewire/DashboardStats.php
):
use Illuminate\Support\Facades\Auth;
public function mount() {
// Block unauthorized access
if (!Auth::user()->can('view-dashboard')) {
abort(403);
}
}
@can('edit-post')
. Go build your fortress! 🏰 With Laravel 12 and Livewire, you’ve got the keys to a secure, scalable app.
Pro Tip: Test permissions with
php artisan tinker
:$user = User::first(); $user->can('delete-post'); // Returns true/false
Questions? Drop them below! 👇 Let’s refine your access control superpowers.
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google