Laravel Roles and Permissions: Middleware, Gates or Policies?

When creating an application, you will need some restrictions for your users. Laravel offers a variety of ways how to implement this. In this tutorial, I will show you four examples:

  • Simple Middleware
  • Restriction with Gates
  • From Gates to Policies
  • Roles in DB with Model

There are also well-known packages like spatie/laravel-permission, but for the purpose of this article, I deliberately want to show what Laravel offers in its core, without external packages.


Scenario Setup

In this example, we will work with Users and Tasks and allow different users to access different pages related to the tasks.

Here's our setup:

Migrations

Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->boolean('is_admin')->default(0);
$table->rememberToken();
$table->timestamps();
});
 
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('name');
$table->date('due_date');
$table->timestamps();
});

Now, let's define the relationships:

app/Models/User.php

use App\Models\Task;
 
// ...
 
public function tasks()
{
return $this->hasMany(Task::class);
}

app/Models/Task.php

use App\Models\User;
 
// ...
 
public function user()
{
return $this->belongsTo(User::class);
}

Example 1. Middleware: Different Pages by User Role

In this example, we'll separate our routes/models and controllers by user role. It means that we will have two pages - one for the simple user and one for the admin, and we will restrict it with Middleware.

So, we generate this Middleware class:

php artisan make:middleware IsAdmin

app/Http/Middleware/IsAdmin.php

public function handle(Request $request, Closure $next): Response
{
if (!auth()->check() || !auth()->user()->is_admin) {
abort(403);
}
return $next($request);
}

As you can see, we just have the field users.is_admin in the DB and filter by that.

Next, we need to...

The full tutorial [10 mins, 1840 words] is only for Premium Members

Login Or Become a Premium Member for $129/year or $29/month
What else you will get:
  • 55 courses (987 lessons, total 46 h 42 min)
  • 77 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials