How to Add Role & Permission Management in Laravel 12 — Beginner’s Guide

How to Add Role & Permission Management in Laravel 12 — Beginner’s Guide

Introduction

In this tutorial, you will learn how to add Role & Permission Management to your Laravel 12 CRUD app using the Spatie Laravel Permission package.

This allows you to assign roles (like Admin, Editor, User) and control what each role can do — such as creating, editing, or deleting posts.

Requirements

Before we start, make sure you have:

  • A working Laravel 12 CRUD application with user authentication.

  • Composer is installed on your system.

  • Basic knowledge of Laravel routes, controllers, and Blade views.

Step 1 — Install the Spatie Permission Package

Open your terminal and run this command to install the package via Composer:

composer require spatie/laravel-permission

Step 2 — Publish the Configuration and Migration Files

Publish the package’s config file and database migrations:

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

This will create:

  • A config file: config/permission.php

  • Migration files for roles, permissions, and pivot tables.

Step 3 — Run the Migrations

Run the migrations to create the necessary tables:

php artisan migrate

You should now see new tables: roles, permissions, model_has_roles, model_has_permissions, and role_has_permissions.

Step 4 — Add the HasRoles Trait to Your User Model

Open app/Models/User.php and add the following at the top of the class:

use Spatie\Permission\Traits\HasRoles;

Then inside the User class, add the trait:

class User extends Authenticatable { use HasRoles; // ... existing code }

This enables role and permission management on your User model.

Step 5 — Create Initial Roles and Permissions

Create a seeder to add some default roles and permissions:

php artisan make:seeder RolesAndPermissionsSeeder

Edit the seeder file database/seeders/RolesAndPermissionsSeeder.php like this:

namespace Database\Seeders; use Illuminate\Database\Seeder; use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; class RolesAndPermissionsSeeder extends Seeder { public function run() { // Clear cached permissions app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions(); // Create permissions Permission::create(['name' => 'create posts']); Permission::create(['name' => 'edit posts']); Permission::create(['name' => 'delete posts']); // Create roles and assign permissions $admin = Role::create(['name' => 'admin']); $admin->givePermissionTo(Permission::all()); $editor = Role::create(['name' => 'editor']); $editor->givePermissionTo(['create posts', 'edit posts']); $user = Role::create(['name' => 'user']); // no special permissions for regular users } }

Run the seeder:

php artisan db:seed --class=RolesAndPermissionsSeeder

Step 6 — Register Middleware

In Laravel 12, route middleware aliases are no longer registered inside app/Http/Kernel.php.
Instead, you add them in the bootstrap/app.php file.

Open bootstrap/app.php and look for this section (near the bottom):

->withMiddleware(function (Middleware $middleware) { // })

Now replace it (or extend it) with the following code to register Spatie’s middleware:

->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'role' => \Spatie\Permission\Middleware\RoleMiddleware::class, 'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class, 'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class, ]); })

Step 7 — Assign Roles to Users

You can assign roles manually in tinker or add role assignment in your registration logic.

Using tinker:

php artisan tinker
$user = App\Models\User::find(1); // Get user with ID 1 $user->assignRole('admin'); // Assign admin role

Step 8 — Protect Routes Using Middleware

In your routes/web.php, protect routes by role or permission.

Example: Only allow users with the admin role to access certain routes:

use App\Http\Controllers\PostController; Route::middleware(['auth', 'role:admin'])->group(function () { Route::resource('posts', PostController::class); });

Or allow users with the create posts permission to access create route:

Route::get('posts/create', [PostController::class, 'create']) ->middleware(['auth', 'permission:create posts']);

Step 9 — Use Blade Directives to Show/Hide UI Elements

You can use Blade directives in your views to display buttons or links only to users with certain roles or permissions.

Example, in resources/views/posts/index.blade.php:

@can('edit posts') <a href="{{ route('posts.edit', $post) }}" class="btn btn-sm btn-warning">Edit</a> @endcan @role('admin') <form action="{{ route('posts.destroy', $post) }}" method="POST" class="d-inline"> @csrf @method('DELETE') <button class="btn btn-sm btn-danger" onclick="return confirm('Delete this post?')">Delete</button> </form> @endrole

Step 10 — Add Permission Checks in Your Controller

In PostController.php, use middleware and authorization to protect actions:

public function __construct() { $this->middleware('auth'); $this->middleware('permission:create posts')->only(['create', 'store']); $this->middleware('permission:edit posts')->only(['edit', 'update']); $this->middleware('permission:delete posts')->only('destroy'); }

Step 11 — Test Your Role & Permission Setup

  • Create users and assign them different roles.

  • Log in as each user and test if they can perform only allowed actions.

  • Check if unauthorized users are blocked or redirected properly.

Conclusion

You’ve successfully added Role & Permission Management to your Laravel 12 CRUD app using the Spatie Laravel Permission package.

This lets you build scalable apps with fine-grained access control.

Souy Soeng

Souy Soeng

Hi there 👋, I’m Soeng Souy (StarCode Kh)
-------------------------------------------
🌱 I’m currently creating a sample Laravel and React Vue Livewire
👯 I’m looking to collaborate on open-source PHP & JavaScript projects
💬 Ask me about Laravel, MySQL, or Flutter
⚡ Fun fact: I love turning ☕️ into code!

Post a Comment

CAN FEEDBACK
close