Laravel Permission Spatie to handle authorization with roles, installation and about the package

Video thumbnail

Spatie Laravel-Permission is an open source role-based user permissions package for use with Laravel; It is a package that is easy to use when implementing a structure that is so managed in projects today, such as permissions and roles, which we will go into more detail in the next section.

In this section, we will know in detail how to use this package in a Laravel project and with this, be able to protect resources in a more scalable and modular way than simply indicating an enumerated column for the type and role. Remember that we previously saw how to use Test Driven Development (TDD) in Laravel.

Roles and permissions

In typical systems that are required to protect the resources of an application, roles and permissions are used by regulation to manage controlled access to each of the resources; roles and permissions are a mechanism to control access to different parts of a web application.

Permissions are specific actions that a user can perform in the app, for example "post a new article" or "delete a comment". With Spatie laravel-permission, you can associate roles and permissions with users and check if a user has access to a specific action in the app based on the app's roles and permissions.

Roles are a way of grouping permissions, for example, you could have an "administrator" role that has permissions to all actions in your app, while a "user" role would only have permissions for limited actions.

To understand what has been said through an example, in the context of a web application, the roles can be, for example, "administrator", "editor" and "reader". Each role has a different set of permissions that determines what actions it can perform.

For posts in an admin role:

  • Create post.
  • Update post.
  • Delete post.
  • Detail/list post.

For categories in an admin role:

  • Create category.
  • Update category.
  • Delete category.
  • Detail/list category.
  •  

For posts in an editor role:

  • Create post.
  • Update post (only yours).
  • Delete post (only yours).
  • Detail/list post.

For categories in an editor role:

  • Create category.
  • Update category (only yours).
  • Delete category (only yours).
  • Detail/list category.

For posts in a reader role:

  • Detail/list post.

You can get more information at:

https://spatie.be/docs/laravel-permission/v5/introduction

Instalation

The installation of this package has been typical in which we execute a command by composer indicating the package we want to install:

$ composer require spatie/laravel-permission

The provider is registered:

config/app.php

'providers' => [
    *
    Spatie\Permission\PermissionServiceProvider::class,
];

The migration and the configuration file config/permission.php are published to be able to customize it:

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

The migration is executed:

$ php artisan migrate

And we will have an output like the following:

2023_04_16_125650_create_permission_tables ................... 796ms DONE

With the previous command several tables are created, you can inspect the migration of the permissions (*_create_permission_tables) and you will see that it consists of several tables:

  • roles
  • permissions
  • model_has_permissions
  • model_has_roles
  • role_has_permissions

In order to use the permissions from the users entity, we register the roles trait:

use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
    use *** HasRoles;
    ***
}

Policies vs Spatie in Laravel (Roles and Permissions) when to use?

Video thumbnail

I wanted to make a quick clarification about when to use Spatie and when to use Policies in Laravel. I assume you already have a basic understanding of the topic, but I'll explain it quickly.

Role and Permission Systems - Spatie

Spatie is a system that allows you to manage roles and permissions simply. For example, you can assign one or more roles to a user, and each role can have specific permissions to perform certain actions within the application.

Practical Example

Suppose we have a blog-type application with a basic CRUD (create, list, edit, delete). We can define roles such as:

  • Editor: can edit articles and view listings, but not create or delete.
  • Administrator: has access to all CRUD operations.

In practice, Spatie facilitates this logic in a reusable way:

$user->assignRole('admin');
$user->givePermissionTo('edit articles');
if ($user->can('edit articles')) {
   // Acceso permitido
}

Here, basically, permissions translate into conditionals that control access to resources. The advantage is that you can easily reuse these permissions and assign them to both users and roles.

What are Policies in Laravel

Policies are a more customized, in-house system that allows you to control access to resources based on your application's business logic. They are ideal when you don't need a complex role and permission system, like the one offered by Spatie.

Practical Example

In my application, I have a system for books and courses. Every time a user buys a book, a record is generated in the database:

$filePayment = FilePayment::where('user_id', $user->id)
   ->where('file_paymentable_id', $bookSection->book->id)
   ->where('file_paymentable_type', Book::class)
   ->first();
if ($filePayment == null) return [202, "You have not purchased the book"];

This is a good candidate for defining a Policy, which would be responsible for validating whether the user has access to the book's content. This way, you avoid repeating conditionals in multiple places in the application.

Policies are tied to business logic and models. While Spatie is more generic and geared towards large systems, Policies allow for finer control over specific resources and logical steps within the application.

Basically, everything translates into conditionals. The functions we see in Spatie act as intermediaries for a conditional, but deep down, we are always evaluating whether a user has or doesn't have a permission:

$user->assignRole('admin');
$user->givePermissionTo('edit articles');
if ($user->can('edit articles')) { // Access granted }

With this, we have simple permission reuse: you can assign a permission to several users and check it uniformly.

This system is very similar to what we find in Django, although in Laravel with Spatie, it easily integrates with other components, such as Policies. For example, you can:

Assign a role to a user.

Give permissions to that role automatically or independently.

This way, Spatie takes care of managing permissions for you, and from there you only apply conditionals to verify if a user can perform an action, for example:

can('edit articles')

You simply ask if the user has that permission, and that's it.

What are Policies

Now, what is a Policy?
Policies are similar to Spatie, but a little more generic and focused on your application's business logic. They are typically used when you don't need a complex role and permission system.

In other words, while Spatie handles permissions and roles globally and reusably, Policies allow you to define more specific rules directly tied to your application's models or resources.

In the following practical example, we will see how to use Policies to control access to certain resources without relying on a complete role and permission system.

Integration between Spatie and Policies

In more complex applications, you can combine Spatie and Policies:

  • Spatie: defines general roles and permissions.
  • Policies: implements specific rules based on business logic.

For example, you could have permissions to access books and, within a Policy, validate that the user has actually purchased that book before allowing them to view the content.

Summary

  • Spatie: generic role and permission system, useful for large applications with many users and roles.
  • Policies: more specific control tied to business logic and models, ideal for validating resource access granularly.

In summary, Policies focus on your application's internal logic, while Spatie provides a general schema of reusable permissions. Both can be combined according to your project's needs.

The next step we'll look at is how to integrate CKEditor into Laravel.

I agree to receive announcements of interest about this Blog.

We will talk about Laravel Spatie and installing it in a Laravel project.

| 👤 Andrés Cruz

🇪🇸 En español