Diferencia entre revisiones de «Usuario:ManuelRomero/Laravel/Roles»

De WikiEducator
Saltar a: navegación, buscar
 
(18 revisiones intermedias por el mismo usuario no mostrado)
Línea 1: Línea 1:
 
===Qué es un sistema de roles===
 
===Qué es un sistema de roles===
 +
<div class=parrafo>
 +
<br />
 +
{{MRM_Resumen|Title=Métodos más usados|
 +
;Para recuperar los roles un usuario
 +
<source lang=php>
 +
$roles= auth()->user()->getRoleNames()
 +
</source>
 +
 +
 +
;Para recuperar un rol de un usuario en la vista (sé que solo tiene uno)
 +
<source lang=php>
 +
$rol= auth()->user()->getRoleNames()[0]
 +
</source>
 +
 +
;Ver su un usuario tiene un determinado rol
 +
<source lang=php>
 +
  @hasanyrole(["gestor","administrador"])
 +
  .....
 +
  @elsehasanyrole
 +
    ........
 +
  @endhasanyrole
 +
</source>
 +
 +
 +
 +
}}
 
*Es una utilidad que suelen tener muchas aplicaciónes donde hay diferentes secciones en nuestro sistema
 
*Es una utilidad que suelen tener muchas aplicaciónes donde hay diferentes secciones en nuestro sistema
*Es algo muy típico y muy bien implementado en los csm, que básicamente consiste es que:
+
*Es algo muy típico y muy bien implementado en los csm, que básicamente consiste en:
 +
{{MRM_Resumen|Title=Ideas sobre un sistema de roles en una aplicación|
 
1.- Te identificas en el sistema<br />
 
1.- Te identificas en el sistema<br />
2.- En fucnión de tus credenciales puedes realizar determinadas acciones en el sistema<br />
+
2.- En función de tus credenciales puedes realizar determinadas acciones en el sistema<br />
 
3.- Se identifican roles y a cada rol se le asignan determinadas acciones (dar de alta usuarios, subir noticias, modificar clientes ...)<br />
 
3.- Se identifican roles y a cada rol se le asignan determinadas acciones (dar de alta usuarios, subir noticias, modificar clientes ...)<br />
 
4.- A los diferentes usuarios se les asisigna un rol concreto, con lo que puede realizar las acciones que a ese rol se le han atribuído<br />
 
4.- A los diferentes usuarios se les asisigna un rol concreto, con lo que puede realizar las acciones que a ese rol se le han atribuído<br />
5.- Lo mismo puedo asignar directamente permisos concretos, pero es mucho más útil asigar un rol concreto a un determinado usuario en lugar de dar permiso a permiso<br />
+
5.- El sistema es tremendamente flexible, puedo asignar permisos concretos (pe. facturas.read o clientes.create representando la acción de leer de la tabla facturas o crear nuevos clientes) a un rol que tenga un usuario o directamente a un usuario.
 +
5.- Muchas veces, simplemente con un rol, podemos dejar establecido este sistema de permisos, otras veces tendremos que usar permisos para mayor detalle si así lo necesitamos.<br />
 +
}}
  
 +
;Para este post, vamos a implementar un ejemplo de una aplicación donde tenemos la siguiente situación.
 +
*Una app que gestiona a nivel de CRUD las sigueintes tablas
 +
 +
[[Archivo:modelo_relacional_roles.png|center|800px]]
 +
<hr />
 +
*Y queremos establecer el siguiente sistema de permisos que pretende dejar claro el diagrama siguiente
 
[[Archivo:DigramaGenearlRoles.png|center|400px]]
 
[[Archivo:DigramaGenearlRoles.png|center|400px]]
 +
 
===Paquetes para gestionar roles en Laravel===
 
===Paquetes para gestionar roles en Laravel===
*Vamos  a utilizar el paquete '''''laravel-permission''''' para gestionar estas acciones en nuestro poryecto
+
*Vamos  a utilizar el paquete '''''laravel-permission''''' para gestionar estas acciones en nuestro proyecto (A la fecha de este post la versión de este paquete es la V5.9)
 
{{MRM_Web|
 
{{MRM_Web|
 
https://spatie.be/docs/laravel-permission/v5/introduction
 
https://spatie.be/docs/laravel-permission/v5/introduction
 
}}
 
}}
https://www.youtube.com/watch?v=r5Zs9CGB754
 
 
 
*Blog en la web :'''''https://blog.pleets.org/article/sistema-basado-en-roles-con-laravel-permission'''''
 
  
  
Línea 119: Línea 151:
 
*Ahora tendremos que crear los roles y permisos, según necesitemos en nuestra aplicación
 
*Ahora tendremos que crear los roles y permisos, según necesitemos en nuestra aplicación
 
*Como hemos comentado un Rol, puede tener asociado uno o varios permisos, cada uno de los cuales puede estar asociado a uno o varios roles.
 
*Como hemos comentado un Rol, puede tener asociado uno o varios permisos, cada uno de los cuales puede estar asociado a uno o varios roles.
*Vamos a crear 3 roles para nuestro ejemplo:
+
*Siguiendo con nuestro ejemplo, vamos a crear 3 roles:
#Alumno
+
[[Archivo:DigramaGenearlRoles.png]]
#Profesor
+
 
#Administrador
+
 
<source lang=bash>
 
<source lang=bash>
 
use Spatie\Permission\Models\Role;
 
use Spatie\Permission\Models\Role;
 
use Spatie\Permission\Models\Permission;
 
use Spatie\Permission\Models\Permission;
  
$role = Role::create(['name' => 'alumno']);
+
 
 
$role = Role::create(['name' => 'administrador']);
 
$role = Role::create(['name' => 'administrador']);
$role = Role::create(['name' => 'profesor']);
+
$role = Role::create(['name' => 'gestor']);
 +
$role = Role::create(['name' => 'comercial']);
  
 
$permission = Permission::create(['name' => 'edit articles']);
 
$permission = Permission::create(['name' => 'edit articles']);
  
 
</source>
 
</source>
*Este código lo tendremos que ejecutar cuando queramos creare el roll, en un controlador. Pero muchas veces, la creación de roles, no será algo dinámico en nuestra aplicación, otras veces sí.
+
*Este código lo tendremos que ejecutar cuando queramos crear el roll, en un controlador. Pero muchas veces, la creación de roles, no será algo dinámico en nuestra aplicación, otras veces sí.
 
*Suponemos que queremos tener creados estos tres roles, y ya no se van a crear más. Para ello lo mejor es crear un seeder que alimente la tabla de roles con estos valores.
 
*Suponemos que queremos tener creados estos tres roles, y ya no se van a crear más. Para ello lo mejor es crear un seeder que alimente la tabla de roles con estos valores.
*Creamos el seeder, si previamente ya lo hemos creado lo usamos
+
*Usamos el seeder creado previamente en este ejemplo (si no lo existiera lo tendríamos que crear)
  
 
<source lang=bash>
 
<source lang=bash>
php artisan make:seeder CreaRoles
+
php artisan make:seeder RolesSeeder
 
</source>
 
</source>
 
*Editamos el fichero que se ha creado '''''database/seeders/RoleSeeder.php'''''
 
*Editamos el fichero que se ha creado '''''database/seeders/RoleSeeder.php'''''
Línea 153: Línea 185:
 
</source>
 
</source>
 
*Y para ejecutarlo modificamos el método Run de la clase '''''DatabaseSeeder.php'''''
 
*Y para ejecutarlo modificamos el método Run de la clase '''''DatabaseSeeder.php'''''
    public function run()
 
    {
 
        $roles  =["administrador","profesor", "alulmno"];
 
        foreach ($roles as $role) {
 
            Role::create(["name"=>$role]);
 
        }
 
        //
 
    }
 
 
<source lang=php>
 
<source lang=php>
 
     public function run()
 
     public function run()
Línea 173: Línea 197:
 
  php artisan db:seed  
 
  php artisan db:seed  
 
</source>
 
</source>
 +
*O  bien establecer toda la carga completa de la base de datos
 +
<source lang=bash>
 +
php artisan migrate:fresh --seed
 +
</source>
 +
 +
===Creando Roles y Permisos===
 
===Asignando roles a un usuario===
 
===Asignando roles a un usuario===
 +
*Vamos a crear un usuario para cada uno de los grupos
 +
*Otra práctica sería que al crearse un usuario, no tenga ningún rol asignado (o se podría crear uno muy básico)
 +
*Posteriormente el adminsitrador/a de la aplicación le podrá asignar un rol, o podrá modificar los roles de los usuarios
 +
*Vamos con la primera parte
 +
====Crear un usuario para cada roll en la aplicación====
 +
;Creamos un seed para usuarios
 +
<source lang=bash>
 +
php artisan make:seed SeedUsers
 +
</source>
 +
;Lo poblamos con valores y le asignamos roles
 +
*Hay que tener en cuenta que este seeder, habrá que ejecutarlo después de que se hayan creado los roles y permisos
 +
*En este caso, no hace falta permisos, ya que vamos a gestionar el ejemplo solo con roles como se puede ver en la imagen anterior
 +
{{MRM_Puntos clave|Title=Asiganr un rol a un usuario|
 +
<source lang=php>
 +
$user->assignRole('nombre_rol');
 +
</source>
 +
}}
 +
<source lang=bash>
 +
php artisan make:seed SeedUsers
 +
</source>
 +
*Y establecemos la población de usuarios (creamos 3 usuarios)
 +
<source lang=bash>
 +
public function run(): void
 +
    {
 +
        //
 +
        $datos=[
 +
            'name' => 'administrador',
 +
            'email' => 'a@a.com',
 +
            'email_verified_at' => now(),
 +
            'password' =>  bcrypt('12345678'), // password
 +
            'remember_token' => Str::random(10),
 +
        ];
 +
        $user = new User($datos);
 +
        $user->assignRole('administrador');
 +
        $user->saveOrFail();
 +
 +
        $datos=[
 +
            'name' => 'comercial',
 +
            'email' => 'c@c.com',
 +
            'email_verified_at' => now(),
 +
            'password' =>  bcrypt('12345678'), // password
 +
            'remember_token' => Str::random(10),
 +
        ];
 +
        $user = new User($datos);
 +
 +
        $user->assignRole('comercial');
 +
        $user->saveOrFail();
 +
        $datos=[
 +
            'name' => 'gestor',
 +
            'email' => 'g@g.com',
 +
            'email_verified_at' => now(),
 +
            'password' =>  bcrypt('12345678'), // password
 +
            'remember_token' => Str::random(10),
 +
        ];
 +
        $user = new User($datos);
 +
        $user->assignRole('gestor');
 +
        $user->saveOrFail();
 +
    }
 +
</source>
 +
 +
.....
 +
 +
*Ahora hay que proteger las páginas y obligar a que el usuario se registre con el middleware auth
 +
*En lugar de proteger cada ruta, establecemos un grupo
 +
<source lang=php>
 +
Route::middleware('auth')->group(function () {
 +
    Route::resource("clientes", \App\Http\Controllers\ClienteController::class);
 +
    Route::resource("facturas", \App\Http\Controllers\FacturaController::class);
 +
    Route::resource("empleados", \App\Http\Controllers\EmpleadoController::class);
 +
    Route::view('/', 'acceso')->name("main");
 +
});
 +
</source>
 +
 +
====Administrar los roles en la propia aplicación====
 +
Cremos los tres usuarios
 
*En el modelo especificamos que vamos a usar roles especificando que vamos a usar  '''''HasRoles'''''
 
*En el modelo especificamos que vamos a usar roles especificando que vamos a usar  '''''HasRoles'''''
 
<source lang=php>
 
<source lang=php>
Línea 185: Línea 290:
 
}
 
}
 
</source>
 
</source>
 +
 
==Roles en inertia===
 
==Roles en inertia===
 
https://dev.to/eduloper/roles-y-permisos-en-laravel-jetstream-con-inertia-js-3b30
 
https://dev.to/eduloper/roles-y-permisos-en-laravel-jetstream-con-inertia-js-3b30

Última revisión de 22:24 27 ago 2023

Qué es un sistema de roles



Icon summary.gif
Métodos más usados
Para recuperar los roles un usuario
$roles= auth()->user()->getRoleNames()


Para recuperar un rol de un usuario en la vista (sé que solo tiene uno)
$rol= auth()->user()->getRoleNames()[0]
Ver su un usuario tiene un determinado rol
  @hasanyrole(["gestor","administrador"])
   .....
  @elsehasanyrole
    ........ 
  @endhasanyrole




  • Es una utilidad que suelen tener muchas aplicaciónes donde hay diferentes secciones en nuestro sistema
  • Es algo muy típico y muy bien implementado en los csm, que básicamente consiste en:


Icon summary.gif
Ideas sobre un sistema de roles en una aplicación

1.- Te identificas en el sistema
2.- En función de tus credenciales puedes realizar determinadas acciones en el sistema
3.- Se identifican roles y a cada rol se le asignan determinadas acciones (dar de alta usuarios, subir noticias, modificar clientes ...)
4.- A los diferentes usuarios se les asisigna un rol concreto, con lo que puede realizar las acciones que a ese rol se le han atribuído
5.- El sistema es tremendamente flexible, puedo asignar permisos concretos (pe. facturas.read o clientes.create representando la acción de leer de la tabla facturas o crear nuevos clientes) a un rol que tenga un usuario o directamente a un usuario. 5.- Muchas veces, simplemente con un rol, podemos dejar establecido este sistema de permisos, otras veces tendremos que usar permisos para mayor detalle si así lo necesitamos.


Para este post, vamos a implementar un ejemplo de una aplicación donde tenemos la siguiente situación.
  • Una app que gestiona a nivel de CRUD las sigueintes tablas
Modelo relacional roles.png

  • Y queremos establecer el siguiente sistema de permisos que pretende dejar claro el diagrama siguiente
DigramaGenearlRoles.png

Paquetes para gestionar roles en Laravel

  • Vamos a utilizar el paquete laravel-permission para gestionar estas acciones en nuestro proyecto (A la fecha de este post la versión de este paquete es la V5.9)




  • Lo primero que necesitamos es tener una aplicación desarrollada.
  • Vamos a realizar una donde tengamos el siguiente esquema.
  • Por supuesto en nuestra aplicación el usuario se tiene que autentificar para acceder
  • En nuestra aplicación vamos a gestionar Facturas y Clientes pudiendo un cliente tener varias facturas y pudiendo ser una factura de hasta 6 clientes. Por otro lado gestionamos Empleados e Idiomas que habla cada empleado, siendo éste un atributo multivaluado que mostramos en tabla
Modelo relacional roles.png

1.- Crear modelos, crontroladores, migraciones, seeder y factory y resources para cada elemento
2.- Creemos el crud de, por ejemplos las facturas
3.- Activamos el sistema de autenticación de laravel con

  • Ahora agregamos o instalamos el paquete en nuestro proyecto
  composer require spatie/laravel-permission
  • Para que autocomplete en phpstorm los métodos
  • Las opciones se pueden encontrar en File->Setting->PHP->Blade
https://spatie.be/docs/laravel-permission/v5/advanced-usage/phpstorm
  • Una vez que tenemos creada la aplicación vamos a realizar los roles y permisos

Creamos un seeder para poblar los roles y permisos

php artisan make:seed RoleSeeder
Icon present.gif
Tip: Seguimos el post arriba indicado


  • Registramos el proveedor de servicios añadiendolo en el fichero config/app.php
'providers' => [
    // ...
    Spatie\Permission\PermissionServiceProvider::class,
];
  • Publicamos la migración y el fichero de configuración de 'permission config/permission.php:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
  • Borramos si lo tuviéramos cacheada la cofiguracioń de los ficheros, habría que borrarla para que la vuelva a cargar


 php artisan optimize:clear
 # or
 php artisan config:clear
  • Ejecutamos las migraciones
php artisan migrate
  • Observamos que ha creado las siguientes tablas

Modelo relacional permission.png

  • Tenemos roles y permisos. Cada rol tendrá asociado permisos (uno o varios) y a su vez, cada permiso tendrá asociado roles (1 o varios), por eso la tabla role_has_permissions.


Icon casestudy.gif
ejemplos de roles y permisos
  • Los roles los crearemos nosotros, por ejemplo:
 administrador o contabilidad o alumno ...
  • Los permisos son acciones concretas que se asocian a modelos, y también tendrán un nombre que los asignaremos nosotros
all_facturas (representaría todos los permisos en la tabla(modelo) facturas)
read_faturas (representaría que solo se puede leer la tabla(modelo) facturas)



Tanto los permisos, como los roles, se asocia a modelos (tablas model_has_roles, model_has_permissons).


  • Creamos las tablas con las migraciones creadas
  1. role_has_permissions
  2. model_has_roles
  3. model_has_permissions
  4. roles
  5. permissions
  • La siguiente imagen muestra las tablas relacionadas
Modelo relacional spite roles.png


  • Este paquete implementa un trait HasRoles (https://diego.com.es/traits-en-php) el cual hay que incorporar a la tabla User, ya que se pretende dar a cada usuario permisos específicos o grupo de permisos (roles)
...
use Spatie\Permission\Traits\HasRoles;
 
class User extends Authenticatable
{
    use Notifiable, HasRoles;
 
    ...
}

Creando Roles y Permisos

  • Ahora tendremos que crear los roles y permisos, según necesitemos en nuestra aplicación
  • Como hemos comentado un Rol, puede tener asociado uno o varios permisos, cada uno de los cuales puede estar asociado a uno o varios roles.
  • Siguiendo con nuestro ejemplo, vamos a crear 3 roles:

DigramaGenearlRoles.png

use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
 
 
$role = Role::create(['name' => 'administrador']);
$role = Role::create(['name' => 'gestor']);
$role = Role::create(['name' => 'comercial']);
 
$permission = Permission::create(['name' => 'edit articles']);
  • Este código lo tendremos que ejecutar cuando queramos crear el roll, en un controlador. Pero muchas veces, la creación de roles, no será algo dinámico en nuestra aplicación, otras veces sí.
  • Suponemos que queremos tener creados estos tres roles, y ya no se van a crear más. Para ello lo mejor es crear un seeder que alimente la tabla de roles con estos valores.
  • Usamos el seeder creado previamente en este ejemplo (si no lo existiera lo tendríamos que crear)
 php artisan make:seeder RolesSeeder
  • Editamos el fichero que se ha creado database/seeders/RoleSeeder.php
    public function run()
    {
        $roles  =["administrador","profesor", "alulmno"];
        foreach ($roles as $role) {
            Role::create(["name"=>$role]);
        }
        //
    }
  • Y para ejecutarlo modificamos el método Run de la clase DatabaseSeeder.php
    public function run()
    {
        $this->call([
            RoleSeeder::class
        ]);
    }
  • Ahora ya podemos ejectuarlo
 php artisan db:seed
  • O bien establecer toda la carga completa de la base de datos
 php artisan migrate:fresh --seed

Creando Roles y Permisos

Asignando roles a un usuario

  • Vamos a crear un usuario para cada uno de los grupos
  • Otra práctica sería que al crearse un usuario, no tenga ningún rol asignado (o se podría crear uno muy básico)
  • Posteriormente el adminsitrador/a de la aplicación le podrá asignar un rol, o podrá modificar los roles de los usuarios
  • Vamos con la primera parte

Crear un usuario para cada roll en la aplicación

Creamos un seed para usuarios
 php artisan make:seed SeedUsers
Lo poblamos con valores y le asignamos roles
  • Hay que tener en cuenta que este seeder, habrá que ejecutarlo después de que se hayan creado los roles y permisos
  • En este caso, no hace falta permisos, ya que vamos a gestionar el ejemplo solo con roles como se puede ver en la imagen anterior


Icon key points.gif

Asiganr un rol a un usuario

 $user->assignRole('nombre_rol');


 php artisan make:seed SeedUsers
  • Y establecemos la población de usuarios (creamos 3 usuarios)
public function run(): void
    {
        //
        $datos=[
            'name' => 'administrador',
            'email' => 'a@a.com',
            'email_verified_at' => now(),
            'password' =>  bcrypt('12345678'), // password
            'remember_token' => Str::random(10),
        ];
        $user = new User($datos);
        $user->assignRole('administrador');
        $user->saveOrFail();
 
        $datos=[
            'name' => 'comercial',
            'email' => 'c@c.com',
            'email_verified_at' => now(),
            'password' =>  bcrypt('12345678'), // password
            'remember_token' => Str::random(10),
        ];
        $user = new User($datos);
 
        $user->assignRole('comercial');
        $user->saveOrFail();
        $datos=[
            'name' => 'gestor',
            'email' => 'g@g.com',
            'email_verified_at' => now(),
            'password' =>  bcrypt('12345678'), // password
            'remember_token' => Str::random(10),
        ];
        $user = new User($datos);
        $user->assignRole('gestor');
        $user->saveOrFail();
    }

.....

  • Ahora hay que proteger las páginas y obligar a que el usuario se registre con el middleware auth
  • En lugar de proteger cada ruta, establecemos un grupo
Route::middleware('auth')->group(function () {
    Route::resource("clientes", \App\Http\Controllers\ClienteController::class);
    Route::resource("facturas", \App\Http\Controllers\FacturaController::class);
    Route::resource("empleados", \App\Http\Controllers\EmpleadoController::class);
    Route::view('/', 'acceso')->name("main");
});

Administrar los roles en la propia aplicación

Cremos los tres usuarios

  • En el modelo especificamos que vamos a usar roles especificando que vamos a usar HasRoles
class User extends Authenticatable
{
//....
 
    use HasRoles;
 
//...
}

Roles en inertia=

https://dev.to/eduloper/roles-y-permisos-en-laravel-jetstream-con-inertia-js-3b30