Black Friday: coupon FRIDAY24 for 40% off Yearly/Lifetime membership! Read more here
Courses

Roles and Permissions in Laravel 11

Quick Intro

Welcome to this course about Roles and Permissions. There are many ways to implement them in Laravel, so the goal of this course is to cover the most common scenarios, starting from simple ones and finishing with a complex project.

We will cover:

  • Gates/Policies
  • Popular spatie/laravel-permission package
  • Single/multiple Roles per User
  • Single/multiple Teams per User

The lessons are quite long. Each lesson contains one full project about Task Management with different roles/permissions logic and with a link to the repository/branch at the end.

Each repository includes automated Pest tests. I want to emphasize how important it is to cover permission logic through tests because it's one of the main security risks for projects, with the most significant consequences if it is not tested properly.

So, let's dive into our first project!


The functionality of a Laravel project may be visible to different roles in various ways. In this lesson, we will start with the most typical one: separate areas.

What I mean is to separate ALL Laravel files by role in their sub-folders: for admin and simple user:

  • Separate Controllers
  • Separate Blade Views
  • Separate URL groups/prefixes/names
  • Middleware to check area permissions

Important notice: every lesson in this course will have a repository at the end of the lesson, with automated tests included.

For example, by the end of this first lesson, we will have THIS as a proof that the functions work:


Project Preparation: Task Management System

In this course, our users will manage Tasks like a to-do list.

I deliberately chose a very simple object: we're focusing on roles and permissions here, whatever those users actually use. In real life, you would still need to apply that role-permission logic to your specific projects.

Migration:

Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->date('due_date')->nullable();
$table->foreignId('user_id')->nullable()->constrained();
$table->timestamps();
});

app/Models/Task.php:

namespace App\Models;
 
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
class Task extends Model
{
use HasFactory;
 
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

Admin/User: with is_admin Column

We will create the users.is_admin column for this simple example.

Migration:

Schema::table('users', function (Blueprint $table) {
$table->boolean('is_admin')->default(false);
});

Also, we added it as a fillable column in the model.

app/Models/User.php:

class User extends Authenticatable
{
protected $fillable = [
'name',
'email',
'password',
'is_admin',
];

We will cover more complex examples later in this course. For now, our goal is to showcase the separated areas.


Separate Controllers

We will use Laravel Breeze as a starter kit for this project. So, we have typical Auth Controllers...

This lesson is only for Premium Members.
Want to access all lessons of this course?

You also get:

  • 67 courses (1172 lessons, 43 h 18 min total)
  • Premium tutorials
  • Access to repositories
  • Private Discord