Laravel ‐ Chapter 17 - pierre-akhrass/Lavarel-Docs GitHub Wiki

Chapter 17: Roles and Permissions (Spatie)

Introduction

Managing roles and permissions is a vital part of securing any Laravel application. The Spatie Laravel-Permission package makes this easy, scalable, and elegant.

Instead of manually using a role column on the users table, this package uses tables like roles, permissions, and pivot tables to associate permissions to roles and users.


Goals

We aim to:

  • Create roles like Admin, Editor, Reader
  • Assign permissions to roles
  • Allow roles to perform CRUD operations based on permissions
  • Provide backend interfaces to manage roles and permissions dynamically

Installation and Configuration

1. Install the package

composer require spatie/laravel-permission

2. Publish config and migration files

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

It copies (publishes) the configuration and migration files for the Spatie Laravel Permission package into your own Laravel project so you can:

  • Edit the config file to customize how roles and permissions work.
  • Run the database migration to create the required database tables.

3. Run migrations

php artisan migrate

This creates:

  • roles
  • permissions
  • model_has_roles
  • model_has_permissions
  • role_has_permissions

4. Add Trait to User model

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;
}

Understanding Roles and Permissions

Roles

  • A Role is a group of permissions.
  • Examples: Admin, Editor, Reader.

Permissions

  • Define specific actions.
  • Examples: post.create, post.edit, category.delete.

Example Role Permissions

Role Permissions (Posts) Permissions (Categories)
Admin Create, Update, Delete, List Create, Update, Delete, List
Editor Create, Update/Delete (own only), List Create, Update/Delete (own only), List
Reader View only View only

Creating Roles and Permissions via Seeder

Create Seeder

php artisan make:seeder RoleSeeder

Seeder Code

$admin = Role::create(['name' => 'Admin']);
$editor = Role::create(['name' => 'Editor']);

Permission::create(['name' => 'editor.post.index']);
Permission::create(['name' => 'editor.post.create']);
Permission::create(['name' => 'editor.post.update']);
Permission::create(['name' => 'editor.post.destroy']);

Permission::create(['name' => 'editor.category.index']);
Permission::create(['name' => 'editor.category.create']);
Permission::create(['name' => 'editor.category.update']);
Permission::create(['name' => 'editor.category.destroy']);

Run Seeder

php artisan db:seed --class=RoleSeeder

Assigning Roles and Permissions

To Users

$user->assignRole('Editor');
$user->removeRole('Editor');
$user->syncRoles(['Admin', 'Editor']);

To Roles

$role->givePermissionTo('editor.post.create');
$role->revokePermissionTo('editor.post.create');
$role->syncPermissions(['editor.post.create', 'editor.post.update']);

To Permissions

$permission->assignRole('Editor');
$permission->removeRole('Editor');
$permission->syncRoles(['Admin', 'Editor']);

Checking Access

In Controllers

$user->can('editor.post.update');
$user->hasRole('Editor');
$user->hasAnyRole(['Admin', 'Editor']);
$user->hasAllRoles(Role::all());
$user->hasExactRoles(['Admin', 'Editor']);

In Blade Views

@can('editor.post.update')
    <button>Edit</button>
@endcan

Managing Permissions via Components

Features of Manage Component:

  • Display current permissions for a role
  • Assign new permission via dropdown
  • Remove permission with a click
// Assign permission
$role->givePermissionTo($permission);

// Remove permission
$role->revokePermissionTo($permission);

Use Vue/Alpine.js or Laravel Blade + Axios for UI.


Assigning Roles to Users

User > Roles Interface:

  • Show current roles
  • Allow adding/removing roles
  • Update dynamically via JavaScript or form submission

Assigning Permissions to Users

Although not common (since roles usually encapsulate permissions), you can:

$user->givePermissionTo('editor.post.create');
$user->revokePermissionTo('editor.post.create');

Notes

  • Spatie-Permission integrates perfectly with Laravel Gates and Policies.
  • Use middleware to protect routes:
Route::middleware(['role:Admin'])->group(function () {
    // admin-only routes
});

⚠️ **GitHub.com Fallback** ⚠️