Laravel Permission/Permisos Spatie para manejar la autorización con roles, instalación y sobre el paquete

- Andrés Cruz

In english
Laravel Permission/Permisos Spatie para manejar la autorización con roles, instalación y sobre el paquete

Este material forma parte de mi curso y libro completo; puedes adquirirlos desde el apartado de libros y/o cursos Curso y libro Laravel 11 con Tailwind Vue 3, introducción a Jetstream Livewire e Inerta desde cero - 2024.

Spatie Laravel-Permission es un paquete para manejar los permisos de los usuarios en base a roles de código abierto que se utiliza con Laravel; es un paquete que fácil de usar al implementar una estructura tan manejada en los proyectos hoy en día como viene siendo el de permisos y roles que entraremos más en detalle en el siguiente apartado.

En esta sección, conoceremos en detalle cómo usar este paquete en un proyecto en Laravel y con esto, poder proteger recursos de una manera más escalable y modular que indicando simplemente una columna de tipo enumerado para el rol.

Roles y permisos

En los sistemas típicos que se requiere proteger los recursos de una aplicación, usualmente se utilizan los roles y permisos para manejar el acceso controlado a cada uno de los recursos; los roles y permisos son un mecanismo para controlar y restringir el acceso a diferentes partes de una aplicación web.

Los permisos son acciones específicas que un usuario puede realizar en la aplicación, por ejemplo, "publicar un nuevo artículo" o "eliminar un comentario". Con Spatie laravel-permission, puedes asociar roles y permisos a usuarios y verificar si un usuario tiene acceso a una acción específica en la aplicación en función de sus roles y permisos.

Los roles son una forma de agrupar permisos, por ejemplo, podrías tener un rol de "administrador" que tiene permisos para todas las acciones en tu aplicación, mientras que un rol de "usuario" solo tendría permisos para acciones limitadas.

Para entender lo comentado mediante un ejemplo, en el contexto de una aplicación web, los roles pueden ser por ejemplo "administrador", “editor" y "lector". Cada rol tiene un conjunto diferente de permisos que determina qué acciones puede realizar.

Para los posts en un rol administrador:

  • Crear post.
  • Actualizar post.
  • Eliminar post.
  • Detalle/Listado post.

Para las categorías en un rol administrador:

  • Crear categoría.
  • Actualizar categoría.
  • Eliminar categoría.
  • Detalle/Listado categoría.

Para los posts en un rol editor:

  • Crear post.
  • Actualizar post (solamente las suyas).
  • Eliminar post (solamente las suyas).
  • Detalle/Listado post.

Para las categorías en un rol editor:

  • Crear categoría.
  • Actualizar categoría (solamente las suyas).
  • Eliminar categoría (solamente las suyas).
  • Detalle/Listado categoría.

Para los posts en un rol lector:

  • Detalle/Listado post.

Para las categorías en un rol lector:

  • Detalle/Listado categoría.

Puedes obtener más información en:

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

https://laravel-news.com/laravel-gates-policies-guards-explained

Instalación

La instalación de este paquete viene siendo lo típico en el cual, ejecutamos un comando por composer indicando el paquete que queremos instalar:

$ composer require spatie/laravel-permission

Se registra el provider:

config/app.php

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

Se publica la migración y el archivo de configuración config/permission.php para poder personalizar el mismo:

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

Se ejecuta la migración:

$ php artisan migrate

Y tendremos una salida como la siguiente:

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

Con el comando anterior se crean varias tablas, puedes inspeccionar la migración de los permisos (***_create_permission_tables) y veras que consta de varias tablas:

  • roles
  • permissions
  • model_has_permissions
  • model_has_roles
  • role_has_permissions

Para poder usar los permisos desde la entidad de los usuarios, registramos el trait de roles:

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use *** HasRoles;
    ***
}

Métodos para asignar: Permisos a roles, roles a permisos y usuarios, permisos y roles

En este apartado vamos a aprender asignar los permisos a cada entidad que corresponda que pueden ser de 3 tipos:

  1. Asignar permisos a roles, este viene siendo el caso más común ya que, al final los roles no son más que una agrupación de permisos es decir, un rol puede tener de cero a N permisos.
  2. Asignar roles a usuarios, un usuario puede tener de cero a N roles, que internamente contienen los permisos y con esto, controlar el acceso a los módulos de la aplicación.
  3. Asignar permisos a usuarios, aunque no es el enfoque ideal, también podemos asignar permisos directamente a los usuarios.

Veamos estos casos en detalle:

Roles a permisos y/o usuarios

Con un permiso o usuario, podemos gestionar los roles de la siguiente manera:

  • removeRole() Remueve un rol al usuario/permiso.
  • assignRole() Asigna un rol al usuario/permiso.
  • syncRoles() Para sincronizar los roles, debes de suministrar un array con los roles:
    • El rol o roles que no se encuentren establecidos como argumentos de esta función pero se encuentran asignados al usuario/permiso, serán removidos.
    • El rol o roles que se encuentren establecidos como argumentos de esta función pero se encuentre asignados al usuario/permiso se mantienen y los que no se encontraban asignados al usuario/permiso se agregaran.

Permisos a roles (o roles a permisos)

Como mencionamos antes, los roles contienen los permisos que definen el acceso a los usuarios; si revisamos el modelo de roles:

vendor\spatie\laravel-permission\src\Models\Role.php

public function permissions(): BelongsToMany{}

Y mediante el trait de:

Spatie\Permission\Traits\HasPermissions;

Veremos que tenemos acceso una serie de métodos equivalentes a los presentados anteriormente:

  • revokePermissionTo()
  • syncPermissions()
  • givePermissionTo()
Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.