Índice de contenido
- Roles y permisos
- Instalación
- Métodos para asignar: Permisos a roles, roles a permisos y usuarios, permisos y roles
- Roles a permisos y/o usuarios
- Permisos a roles (o roles a permisos)
- Políticas vs Spatie en Laravel (Roles y Permisos) ¿cuando usar?
- Sistemas de Roles y Permisos - Spatie
- Qué son las Políticas en Laravel
- Ejemplo práctico
- Asignar un rol a un usuario.
- Qué son las políticas
- Integración entre Spatie y Políticas
- Resumen
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; recuerda que antes vimos como emplear el Test Driven Development (TDD) en Laravel.
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-permissionSe 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 migrateY tendremos una salida como la siguiente:
2023_04_16_125650_create_permission_tables ................... 796ms DONECon 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:
- 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.
- 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.
- 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()
Políticas vs Spatie en Laravel (Roles y Permisos) ¿cuando usar?
Quería hacer una rápida aclaratoria sobre cuándo emplear Spatie y cuándo emplear políticas en Laravel. Asumo que ya tienes un conocimiento básico del tema, pero te lo explico de forma rápida.
Sistemas de Roles y Permisos - Spatie
Spatie es un sistema que permite manejar roles y permisos de manera sencilla. Por ejemplo, puedes asignar a un usuario uno o varios roles, y cada rol puede tener permisos específicos para realizar ciertas acciones dentro de la aplicación.
Ejemplo práctico
Supongamos que tenemos una aplicación tipo blog con un CRUD básico (crear, listar, editar, eliminar). Podemos definir roles como:
- Editor: puede editar artículos y ver listados, pero no crear ni eliminar.
- Administrador: tiene acceso a todas las operaciones del CRUD.
En la práctica, Spatie facilita esta lógica de forma reutilizable:
$user->assignRole('admin');
$user->givePermissionTo('edit articles');
if ($user->can('edit articles')) {
// Acceso permitido
}Aquí, básicamente, los permisos se traducen en condicionales que controlan el acceso a recursos. La ventaja es que puedes reutilizar estos permisos fácilmente y asignarlos tanto a usuarios como a roles.
Qué son las Políticas en Laravel
Las políticas son un sistema más casero y personalizado que permite controlar el acceso a recursos basándose en la lógica de negocio de tu aplicación. Son ideales cuando no necesitas un sistema complejo de roles y permisos, como el que ofrece Spatie.
Ejemplo práctico
En mi aplicación, tengo un sistema de libros y cursos. Cada vez que un usuario compra un libro, se genera un registro en la base de datos:
$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, "No has comprado el libro"];Este es un buen candidato para definir una política, que se encargaría de validar si el usuario tiene acceso al contenido del libro. De esta forma, se evita repetir condicionales en múltiples lugares de la aplicación.
Las políticas están ligadas a la lógica de negocio y a los modelos. Mientras que Spatie es más genérico y orientado a sistemas grandes, las políticas permiten un control más fino sobre recursos específicos y pasos lógicos dentro de la aplicación.
Básicamente, todo se traduce en condicionales. Las funciones que vemos en Spatie actúan como intermediarios de un condicional, pero en el fondo, siempre estamos evaluando si un usuario tiene o no un permiso:
$user->assignRole('admin');
$user->givePermissionTo('edit articles');
if ($user->can('edit articles')) {
// Acceso permitido
}Con esto, tenemos una reutilización sencilla de permisos: puedes asignar un permiso a varios usuarios y verificarlo de manera uniforme.
Este sistema es muy similar al que encontramos en Django, aunque en Laravel con Spatie se integra fácilmente con otros componentes, como las políticas. Por ejemplo, puedes:
Asignar un rol a un usuario.
Dar permisos a ese rol de forma automática o independiente.
De esta manera, Spatie se encarga de gestionar los permisos por ti, y a partir de ahí solo aplicas condicionales para verificar si un usuario puede realizar una acción, por ejemplo:
can('edit articles')Simplemente preguntas si el usuario tiene ese permiso, y listo.
Qué son las políticas
Ahora bien, ¿qué es una política?
Las políticas son similares a Spatie, pero un poco más genéricas y centradas en la lógica de negocio de tu aplicación. Normalmente se utilizan cuando no necesitas un sistema complejo de roles y permisos.
En otras palabras, mientras que Spatie maneja permisos y roles de manera global y reutilizable, las políticas te permiten definir reglas más específicas y ligadas directamente a los modelos o recursos de tu aplicación.
En el siguiente ejemplo práctico, veremos cómo usar políticas para controlar el acceso a ciertos recursos sin depender de un sistema completo de roles y permisos.
Integración entre Spatie y Políticas
En aplicaciones más complejas, puedes combinar Spatie y políticas:
- Spatie: define roles y permisos generales.
- Políticas: implementa reglas específicas basadas en la lógica de negocio.
Por ejemplo, podrías tener permisos para acceder a libros y, dentro de una política, validar que el usuario realmente haya comprado ese libro antes de permitirle ver el contenido.
Resumen
- Spatie: sistema genérico de roles y permisos, útil para aplicaciones grandes y con muchos usuarios y roles.
- Políticas: control más específico ligado a la lógica de negocio y a los modelos, ideal para validar acceso a recursos de forma granular.
En resumen, las políticas se enfocan en la lógica interna de tu aplicación, mientras que Spatie proporciona un esquema general de permisos reutilizables. Ambos pueden combinarse según las necesidades de tu proyecto.
El siguiente paso que veremos es como integrar CKEditor en Laravel.