Configuración de Shinobi
Configuración del paquete de roles Shinobi en Laravel
CREAR PERMISOS CON EL PAQUETE SHINOBI
Una vez instalado el paquete Shinobi como se muestra en la entrada Shinobi en Laravel y después de haber comprobado que las tablas han sido creadas en la base de datos se puede comenzar a crear los permisos.
Los permisos se crean mediante un seeder:
<?php
use Illuminate\Database\Seeder;
use Caffeinated\Shinobi\Models\Permission;
class PermissionTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//Users
Permission::create([
"name" => "Navegar usuarios",
"slug" => "users.index",
"description" => "Lista y navega todos los usuarios del sistema",
]);
Permission::create([
"name" => "Ver detalle de usuario",
"slug" => "users.show",
"description" => "Ver en detalle cada usuario del sistema",
]);
Permission::create([
"name" => "Edición de usuarios",
"slug" => "users.edit",
"description" => "Editar cualquier dato de un usuario del sistema",
]);
Permission::create([
"name" => "Eliminar usuario",
"slug" => "users.destroy",
"description" => "Eliminar cualquier usuario del sistema",
]);
//Roles
Permission::create([
"name" => "Navegar roles",
"slug" => "roles.index",
"description" => "Lista y navega todos los roles del sistema",
]);
Permission::create([
"name" => "Ver detalle de rol",
"slug" => "roles.show",
"description" => "Ver en detalle cada rol del sistema",
]);
Permission::create([
"name" => "Creación de roles",
"slug" => "roles.create",
"description" => "Ver en detalle cada rol del sistema",
]);
Permission::create([
"name" => "Edición de roles",
"slug" => "roles.edit",
"description" => "Editar cualquier dato de un rol del sistema",
]);
Permission::create([
"name" => "Eliminar rol",
"slug" => "roles.destroy",
"description" => "Eliminar cualquier rol del sistema",
]);
}
}
El código anterior muestra un ejemplo de un seeder con la creación de una serie de permisos donde cabe destacar que la información almacenada en el dato slug, es la más importante, puesto que es el que transmite el tipo de rol mientras que los otros dos campos solamente son descriptivos.
Una vez creados los permisos solo queda incorporarlo al método run() de la clase DatabaseSeeder y a continuación realizar una migración.
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call([
UserSeeder::class,
PermissionTableSeeder::class,
]);
}
}
Al haber realizado una migración anteriormente es posible que sea necesario añadir la opción fresh o refresh.
php artisan migrate:refresh
CREAR ROLES
El siguiente paso es la creación de un UserSeeder y crear los roles que se necesiten para el proyecto. En caso de no tener claros los tipos de rol se debe añadir uno al menos para realizar las pruebas. En el código de abajo se muestra la creación de varios roles, el dato a destacar es que el rol admin de Shinobi es un tipo de rol especial que permite disponer de acceso total.
<?php
use Illuminate\Database\Seeder;
use Caffeinated\Shinobi\Models\Role;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
factory(App\User::class,22)->create([]);
Role::create([
"name" => "Admin",
"slug" => "admin",
"special" => "all-access"
]);
Role::create([
"name" => "Editor",
"slug" => "editor",
"description" => "Navegar, ver, crear, editar y eliminar",
]);
Role::create([
"name" => "Suscriptor",
"slug" => "suscriptor",
"description" => "Navegar y ver"
]);
}
}
Una vez creados roles y permisos es necesario disponer del módulo auth. En caso de no tenerlo se instala. Este paquete incluye los módulos de registro y login de usuario.
INSTALAR AUTH
php artisan make:auth
REGISTRAR MIDDLEWARES
Lo siguiente es añadir las siguientes líneas al archivo Kernel situado en app/Http/Kernel.php en el array $routeMiddleware. Con esto se registran los middlewares que se encuentran en el paquete Shinobi.
'role' => \Caffeinated\Shinobi\Middleware\UserHasRole::class,
'permission' => \Caffeinated\Shinobi\Middleware\UserHasPermission::class
Con los middlewares registrados es posible completar el archivo de rutas añadiendo los mismos valores slug de los permisos creados en la clase PermissionTableSeeder. A continuación se muestra una lista de rutas dentro del middleware auth. Las rutas añadidas dentro del middleware auth permiten el acceso solamente a usuarios logueados. Esta restricción de acceso es propia del módulo auth e independiente del paquete Shinobi. Para restringir mediante permisos es necesario adjuntar el método middleware a continuación de la ruta y pasando como argumento el permiso requerido, existe otra opción de implementar los middleware de Shinobi, que es pasándolos en el constructor del controlador tal como se muestra en la entrada personalizar Shinobi.
AÑADIR PERMISOS AL ARCHIVO DE RUTAS
routes/web.php
Route::middleware(["auth"])->group(function(){
//Users
Route::get("users","UserController@index")->name("users.index")
->middleware("permission:users.index");
Route::put("users/{user}","UserController@update")->name("users.update")
->middleware("permission:users.edit");
Route::get("users/{user}","UserController@show")->name("users.show")
->middleware("permission:users.show");
Route::delete("users/{user}","UserController@destroy")->name("users.destroy")
->middleware("permission:users.destroy");
Route::get("users/{user}/edit","UserController@edit")->name("users.edit")
->middleware("permission:users.edit");
//Roles
Route::post("roles/store","RoleController@store")->name("roles.store")
->middleware("permission:roles.create");
Route::get("roles","RoleController@index")->name("roles.index")
->middleware("permission:roles.index");
Route::get("roles/create","RoleController@create")->name("roles.create")
->middleware("permission:roles.create");
Route::put("roles/{role}","RoleController@update")->name("roles.update")
->middleware("permission:roles.edit");
Route::get("roles/{role}","RoleController@show")->name("roles.show")
->middleware("permission:roles.show");
Route::delete("roles/{role}","RoleController@destroy")->name("roles.destroy")
->middleware("permission:roles.destroy");
Route::get("roles/{role}/edit","RoleController@edit")->name("roles.edit")
->middleware("permission:roles.edit");
});
En el código superior se han restringido todos los métodos del crud de usuarios, es decir, que un usuario según su rol asignado puede tener acceso a uno, varios o todos los permisos dependiendo del alcance de ese rol.
De esta forma se restringe el acceso desde las rutas, pero todavía queda por restringir el acceso a las vistas. Para restringir de forma sencilla acceso a un botón, un enlace o una sección que el usuario no tiene acceso, Shinobi dispone de helpers que permiten restringir el acceso de forma visual.
@can("users.index")
<li >
<a class="nav-link" href="{{ route('users.index') }}">Usuarios</a>
</li>
@endcan
Nota: Recuerda que en los paréntesis se debe indicar el nombre del permiso y no de la ruta que pudiendo ser iguales puede llevar a confusión. Para entender mejor esta posible confusión es necesario observar más detenidamente el código de arriba correspondiente al archivo de rutas (routes/web.php). Al analizar los permisos uno a uno se contempla que algunos permisos están duplicados, es decir, que el mismo permiso sirve para dos rutas distintas. En concreto el método update y el método edit requieren del permiso users.edit permitiendo el acceso a las dos rutas.
CREAR CONTROLADOR DE USUARIOS
Como el código de ejemplo mostrado anteriormente está dirigido a los métodos para usuarios, es necesario para las pruebas de roles disponer de tres requisitos: un controlador para los usuarios, un usuario registrado y un rol asociado a ese usuario.
php artisan make:controller UserController --resource
@if (Route::has('login'))
<div class="top-right links">
@auth
<a href="{{ url('/home') }}">Home</a>
@else
<a href="{{ route('login') }}">Login</a>
<a href="{{ route('register') }}">Register</a>
@endauth
</div>
@endif
Con el rol Admin asignado al usuario registrado, este usuario es considerado administrador con acceso total, es decir, puede acceder a cualquier ruta, requiera o no requiera permisos. El rol Admin dispone de un campo especial que permite tres posibles valores: all-access, no-access y null. Si el valor pasa a null el usuario deja de ser especial y se comporta como cualquier otro usuario dependiendo de los roles asignados.
AÑADIR TRAIT
El módulo está listo para asignarle los permisos a los usuarios, pero para que el sistema reconozca el sistema de roles es necesario añadir el archivo ShinobiTrait al modelo User como viene añadido en el siguiente fragmento de código ( el código de color fucsia representa las líneas añadidas).
<?php
namespace App;
use Caffeinated\Shinobi\Traits\ShinobiTrait;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable,ShinobiTrait;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
}
Una vez configurado el sistema de roles junto al módulo auth es posible crear los controladores y las vistas para que el administrador pueda manejar tanto las listas de usuarios como la de roles y así poder personalizar el sistema.
Para poder comentar es necesario iniciar sesión