Roles de usuario en Laravel

Los roles de usuario son algo fundamental en cualquier aplicación que haga uso de autetificación. Es un modo de identificar que tipo de usuario ha iniciado sesión y de esta forma elegir a donde llevarlo, qué mostrarle, qué puede y no hacer.

En este artículo vamos a aprender a utilizar roles en Laravel con el uso de la librería Spatie.

Añadiendo librería de roles en Laravel

Debemos instalar Spatie para comenzar a trabajar con roles en nuestra aplicación Laravel. Lo Instaremos mediante este comando de composer:

composer require spatie/laravel-permission

Una vez se termine la instalación, nos dirigimos al archivo app.php, que se encuentra en la carpeta config y vamos al apartado de providers, dónde añadiremos el de la librería instalada:

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

 Ahora, generaremos el archivo config y el archivo de migraciones de la librería, de esta forma:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"

Por último, ejecutaremos el comando de migraciones para añadir las nuevas tablas (que utilizará la librería) en nuestra base de datos:

php artisan migrate

Y se añadirán estas tablas en nuestra base de datos:

Creando roles en Laravel

Ahora que ya tenemos nuestra librería configurada, vamos a comenzar a utilizarla. Lo primero que vamos a crear es el típico rol de cliente de tienda online, utilizando tinker en nuestra consola:

php artisan tinker

Y ahora crearemos el rol de «Cliente» con el siguiente código:

use Spatie\Permission\Models\Role;

$role = Role::create(['name' => 'cliente']);

Añadir rol a usuarios

Ahora que ya tenemos creado nuestro rol de prueba «Cliente», nos vamos a dirigir al modelo de usuarios, que se encuentra en la carpeta app con el nombre de User.php.  Vamos a añadir en este modelo las siguientes lineas de código, para hacer accesible a éste a la librería de roles:

<?php

namespace App;

...
...
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    ...
    use HasRoles;

    ...
}

Y ahora que nuestros roles son accesible desde el modelo user, podemos crear un registro para los clientes de la tienda, dónde se le asigne el rol de clientes en cuanto se registren.

Para ello creariamos una función, en el controlador que queramos, para hacer uso de ella desde el formulario de registro:

public function registerClient(Request $request){
        // Se crea el usuario con los datos del registro
        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => bcrypt($request->password),
        ]);

        // Le asignamos el rol de Cliente
        $user->assignRole('cliente');
    }

De esta forma, los usuarios que se registrasen tendrían este rol de cliente.

Utilizando roles en Laravel

Como ya hemos dicho, con los roles podemos controlar como interactuar con el usuario, como por ejemplo, mostrandole algo que solo verá si es un cliente registrado:

@if(@Auth::user()->hasRole('cliente'))
    <h2>Eres un cliente</h2>
@endif

De esta forma, accedemos al usuario que esta logeado, comprobamos el rol que tiene y si es un cliente le mostraríamos ese mensaje de ejemplo.

También, podemos crear grupo de rutas añadiendole un middelware con un rol, es decir, solo los del rol especifico podrían entrar en estas rutas.

Añadiendo en kernel.php, que se encuentra en app/Http:

protected $routeMiddleware = [
    // ...
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];

y en nuestro archivo de rutas, web.php:

Route::group(['middleware' => ['role:cliente']], function () {
    //rutas accesibles solo para clientes
});

Trabajando con permisos en roles

Otra forma de controlar las funciones que tiene un rol, es añadiéndole a éste unos permisos.

En este ejemplo, vamos a crear un rol empleado y vamos a darle permisos para que pueda validar una compra:

Como hemos hecho antes, ejecutamos en nuestra terminal tinker:

php artisan tinker

Y ahora crearemos el rol empleado, el permiso para validarCompra y se lo añadiremos al rol:

use Spatie\Permission\Models\Role;

//Creamos el rol empleado
$role = Role::create(['name' => 'empleado']);

use Spatie\Permission\Models\Permission;

//Creamos el permiso validar_venta
Permission::create(['name' => 'validar_venta']);

//Y ahora le asignamos el permiso creado al rol
$role->givePermissionTo('validar_venta');

De esta forma, los usuarios con el rol empleado tendrían el permiso de validar una venta, y una forma de controlar si el usuario tiene dicho permiso, sería con la funcion hasPermissionTo:

@if(@Auth::user()->hasPermissionTo('validar_venta'))
    <button class="btn">Validar venta</button>
@endif