Kritim Yantra
May 08, 2025
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.
✅ 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
laravel/ui
, breeze
, jetstream
, or fortify
)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
composer require spatie/laravel-permission
Publish the config and migration files:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
HasRoles
to User Modelapp/Models/User.php
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
// ...
}
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
You can do this manually or via Tinker:
php artisan tinker
$user = \App\Models\User::find(1);
$user->assignRole('admin');
php artisan make:model Post -mcr
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
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.
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']);
});
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,
];
@role
, @can
, @permission
@role('admin')
<a href="#">Admin Settings</a>
@endrole
@can('post.delete')
<button>Delete Post</button>
@endcan
role_or_permission
middleware for flexible access# 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');
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.
Transform from beginner to Laravel expert with our personalized Coaching Class starting June 20, 2025. Limited enrollment ensures focused attention.
1-hour personalized coaching
Build portfolio applications
Industry-standard techniques
Interview prep & job guidance
Complete your application to secure your spot
Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google