Laravel 12 Roles and Permissions with CRUD Operation – Full Tutorial

Author

Kritim Yantra

May 08, 2025

Laravel 12 Roles and Permissions with CRUD Operation – Full Tutorial

Managing roles and permissions is a critical part of modern web applications. Whether you're building a blog, SaaS, or admin panel — defining who can access what keeps your app secure and organized.

In this tutorial, we’ll walk through setting up roles and permissions in Laravel 12 using the popular Spatie Laravel Permission package, and combine it with CRUD operations to see how access control works in action.


📚 What You'll Learn

✅ Installing Spatie Roles and Permissions package
✅ Creating roles and permissions
✅ Assigning roles to users
✅ Protecting routes and actions
✅ Full CRUD example with role-based access


✅ Prerequisites

  • Laravel 12 installed
  • Basic Laravel knowledge (routes, controllers, models)
  • Authentication set up (laravel/ui, breeze, jetstream, or fortify)
  • PHP, Composer, and a database (MySQL preferred)

🧱 Step 1: Install Laravel 12

composer create-project laravel/laravel laravel12-roles-permissions
cd laravel12-roles-permissions

Set up Laravel authentication:

composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run dev
php artisan migrate

🔌 Step 2: Install Spatie Laravel Permission Package

composer require spatie/laravel-permission

Publish the config and migration files:

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

👥 Step 3: Add HasRoles to User Model

app/Models/User.php

use Spatie\Permission\Traits\HasRoles;

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

🎯 Step 4: Seed Roles and Permissions

Create a seeder:

php artisan make:seeder RolePermissionSeeder

database/seeders/RolePermissionSeeder.php

use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

public function run()
{
    // Create roles
    $admin = Role::create(['name' => 'admin']);
    $editor = Role::create(['name' => 'editor']);

    // Create permissions
    $permissions = ['post.create', 'post.edit', 'post.delete', 'post.view'];
    
    foreach ($permissions as $permission) {
        Permission::create(['name' => $permission]);
    }

    // Assign permissions to roles
    $admin->givePermissionTo(Permission::all());
    $editor->givePermissionTo(['post.create', 'post.edit', 'post.view']);
}

Run the seeder:

php artisan db:seed --class=RolePermissionSeeder

👤 Step 5: Assign Roles to Users

You can do this manually or via Tinker:

php artisan tinker
$user = \App\Models\User::find(1);
$user->assignRole('admin');

🗃️ Step 6: Create a Post CRUD

php artisan make:model Post -mcr

Migration: create_posts_table.php

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('body');
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
    $table->timestamps();
});

Run the migration:

php artisan migrate

📝 Step 7: Implement CRUD in Controller

PostController.php

use App\Models\Post;
use Illuminate\Support\Facades\Auth;

public function index()
{
    $this->authorize('viewAny', Post::class);
    $posts = Post::all();
    return view('posts.index', compact('posts'));
}

public function create()
{
    $this->authorize('create', Post::class);
    return view('posts.create');
}

public function store(Request $request)
{
    $this->authorize('create', Post::class);

    $data = $request->validate([
        'title' => 'required|string|max:255',
        'body' => 'required',
    ]);

    Post::create([
        'title' => $data['title'],
        'body' => $data['body'],
        'user_id' => Auth::id()
    ]);

    return redirect()->route('posts.index')->with('success', 'Post created!');
}

Repeat similar patterns for edit, update, destroy methods.


🛡️ Step 8: Protect Routes with Middleware

routes/web.php

use App\Http\Controllers\PostController;

Route::middleware(['auth'])->group(function () {
    Route::resource('posts', PostController::class);
});

You can also restrict specific routes like:

Route::middleware(['role:admin'])->group(function () {
    Route::delete('/posts/{id}', [PostController::class, 'destroy']);
});

🔐 Step 9: Authorization via Policies (Optional)

You can also create a Policy:

php artisan make:policy PostPolicy --model=Post

In PostPolicy.php, use:

public function delete(User $user, Post $post)
{
    return $user->can('post.delete');
}

Register the policy in AuthServiceProvider.php:

protected $policies = [
    Post::class => PostPolicy::class,
];

🧪 Step 10: Test Access Control

  1. Create users and assign roles
  2. Try accessing routes with unauthorized users
  3. Only users with required permissions should be allowed

💡 Bonus Tips

  • Use blade directives like @role, @can, @permission
@role('admin')
   <a href="#">Admin Settings</a>
@endrole

@can('post.delete')
   <button>Delete Post</button>
@endcan
  • Use role_or_permission middleware for flexible access

📦 Useful Commands Summary

# Create roles/permissions
php artisan make:seeder RolePermissionSeeder

# Assign role
$user->assignRole('editor');

# Give permission
$role->givePermissionTo('post.create');

# Check role/permission
$user->hasRole('admin');
$user->can('post.edit');

🏁 Conclusion

By the end of this tutorial, you now have:

✅ Laravel 12 with role & permission system
✅ CRUD operations protected by role-based access
✅ A scalable access control system

Spatie Laravel Permission is powerful and easy to integrate, making it a perfect choice for managing authorization logic.

LIVE MENTORSHIP ONLY 5 SPOTS

Laravel Mastery
Coaching Class Program

KritiMyantra

Transform from beginner to Laravel expert with our personalized Coaching Class starting June 20, 2025. Limited enrollment ensures focused attention.

Daily Sessions

1-hour personalized coaching

Real Projects

Build portfolio applications

Best Practices

Industry-standard techniques

Career Support

Interview prep & job guidance

Total Investment
$200
Duration
30 hours
1h/day

Enrollment Closes In

Days
Hours
Minutes
Seconds
Spots Available 5 of 10 remaining
Next cohort starts:
June 20, 2025

Join the Program

Complete your application to secure your spot

Application Submitted!

Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.

What happens next?

  • Confirmation email with program details
  • WhatsApp message from our team
  • Onboarding call to discuss your goals

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts

Understanding SOLID Design Principles in Laravel (For Beginners)
Kritim Yantra Kritim Yantra
Feb 24, 2025
Top 10 Essential Laravel 12 Packages for Your Next Project
Kritim Yantra Kritim Yantra
Mar 03, 2025
Understanding Laravel 12 Middleware
Web Development
Understanding Laravel 12 Middleware
Laravel Php
Kritim Yantra Kritim Yantra
Mar 05, 2025