Overview
Managing user roles and permissions is an essential part of most web applications.
You will learn step-by-step how to integrate the Spatie Laravel Permission package to handle role-based access control.
Step 1: Install the Package
Run the following command to install Spatie's permission package:
composer require spatie/laravel-permissionRun For Laravel 10/11:
Add middleware aliases inside app/Http/Kernel.php
protected $routeMiddleware = [
// other middleware...
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
]; Run For Laravel 12
In Laravel 12 you need to add permission in bootstrap/app.php file.
use Spatie\Permission\Middleware\RoleMiddleware;
use Spatie\Permission\Middleware\PermissionMiddleware;
use Spatie\Permission\Middleware\RoleOrPermissionMiddleware;
use Illuminate\Foundation\Configuration\Middleware;
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'role' => RoleMiddleware::class,
'permission' => PermissionMiddleware::class,
'role_or_permission' => RoleOrPermissionMiddleware::class,
]);
})
Step 2: Publish Configuration & Migrations
Now, publish the package’s configuration and migration files:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"- This will create two below files:
- Config -> config/permission.php
- Migration -> database/migrations/*_create_permission_tables.php
Run the migrations to generate all required database tables:
php artisan migrate- The following tables will be created:
- roles
- permissions
- model_has_roles
- model_has_permissions
- role_has_permissions
Step 3: Add the HasRoles Trait to Your User Model
Open app/Models/User.php and add the HasRoles trait:
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles; //Add HasRoles
//Other model code....
}This trait gives your User model access to all role and permission methods — such as assignRole(), hasRole(), givePermissionTo(), and can().
Step 4: Create a Seeder for Roles & Permissions
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
class RolesPermissionsSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Reset cached roles and permissions
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
// Create permissions
$permissions = [
'view users',
'create users',
'edit users',
'delete users',
'view posts',
'create posts',
'edit posts',
'delete posts',
];
foreach ($permissions as $permission) {
Permission::firstOrCreate(['name' => $permission]);
}
// Create roles
$role_admin = Role::firstOrCreate(['name' => 'admin']);
$role_editor = Role::firstOrCreate(['name' => 'editor']);
$role_user = Role::firstOrCreate(['name' => 'user']);
// Assign permissions to roles
$role_admin->givePermissionTo(Permission::all());
$role_editor->givePermissionTo([
'view posts',
'create posts',
'edit posts'
]);
$role_user->givePermissionTo([
'view posts'
]);
}
}
Add your seeder inside DatabaseSeeder.php:
public function run(): void
{
//User::factory(10)->create();
$this->call([
RolesPermissionsSeeder::class,
]);
}
Assign Run Seeder with the following command:
php artisan db:seedAssign role to a User
Route::get('role-assign', function () {
$roles = [
1 => 'admin',
2 => 'author',
3 => 'user',
];
foreach ($roles as $userId => $role) {
if ($user = User::find($userId)) {
$user->assignRole($role);
}
}
return "Roles assigned successfully!";
});Step 5: Check Permissions in Blade or Components
You can easily check roles or permissions directly in your views or Livewire components.
Inside the Livewire component:
public $user;
public $role;
public function mount()
{
$this->user = auth()->user();
if ($this->user && $this->user->hasRole('author')) {
$this->role = 'Author';
} else {
$this->role = 'User';
}
}Inside your Blade view (post-list.blade.php):
@if ($user->can('create_post'))
<a class="btn btn-primary" href="{{ route('post.create') }}">Add Post</a>
@endifStep 6: Protect Routes Using Middleware
You can restrict access to certain routes based on user roles or permissions.
Route::get('/posts/create', Post::class)->name('post.create')->middleware('role:author');Step 7: Clear Caches (important)
Whenever you make role or permission changes, clear your caches:
php artisan optimize:clear
php artisan permission:cache-reset🎉 You’re Done!
You’ve successfully set up Role-Based Access Control in Laravel using the Spatie Permission package.