Aprovecha el precio especial.

Antes:$249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

13d

21h

44m

42s

1

Tutorial para validar el rol de un usuario al momento de hacer una consulta

Tutorial para validar el rol de un usuario al momento de hacer una consulta

Muchas veces, manejamos diferentes roles para los usuarios, de esta manera, por ejemplo, en la app de recetas, tenemos a un Administrador del Restaurante, quien debe ser el único que cree nuevas recetas, un auditor de calidad, quien es el único que puede ver una receta en particular, y tenemos módulos que son para todo el mundo.
Si bien no tengo la misma experiencia que tiene el profe Italo con Laravel, y es probable que mi solución no sea la más linda u optimizada, se las quiero compartir de nivel de tutorial. Los invito a que la usen y la mejoren.
Antes de empezar, les dejo dos prompts importantes por hacerle a Chat Gpt, para que entiendan el trasfonod de las herramientas que les voy a enseñar:

  1. ¿Qué es una relación polimórfica en una Base de datos?
  2. ¿Cómo se pueden implementar permisos por roles en Laravel?

Paso 1. Instalar laravel permission
Laravler permission es la biblioteca standard para manejar roles y permisos en Laravel, hoy solamente vamos a usar la parte de roles, pero quizás alguien se anime a hacer la parte de permisos. Para instalarla se usa el comando:

composer require spatie/laravel-permission

Posteriormente, activa las migraciones y configuraciones de la librería, mediante los comandos
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" php artisan migrate

Lo cual traerá los archivos necesarios y creara las tablas necesarias, recuerda desactivar las configuraciones de phpunit para que se creen de verdad

Paso 2: Crea los roles y asigna los roles a los usuarios

Se debió a ver creado un Seeder que se llama RoleSeeder, si no se creó, crealo.
Dentro del método run, crea los roles de la siguiente manera
$role1 = Role::create(['name' => 'Administrator']); $role2 = Role::create(['name' => 'Auditor']); $role3 = Role::create(['name' => 'User']);

Recuerda que un usuario puede tener varios roles, pero para este caso, haremos que solo tenga 1
Dentro del mismo run, le asignamos al usuario 1 el rol de Administrador, al usuario 2 el rol de auditor, y al resto de los usuarios, el rol de Usuario.
`User::find(1)->assignRole($role1);
User::find(2)->assignRole($role2);

$rest_of_users = User::where(‘id’,‘not in’, ‘(1,2)’)->get();

foreach ($rest_of_users as $key => $each_user) {
$each_user->assignRole($role3);
}`

En el archivo DatabaseSeeder.php, debemos indicarle que ejecute RoleSeeder, colocando al final del método run el siguiente código.
$this->call(RoleSeeder::class);

Hacemos una migración de la base de datos limpia, es decir, le decimos al sistema que borre toda la data y la vuelva a crear con los nuevos cambios; para eso, en consola escribimos:
php artisan migrate:fresh –seed

Si todo sale bien, tendremos en la base de datos la siguiente tabla: model_has_roles

Para entender como funciona la tabla, debes entender sobre relaciones polimórficas, he ahí la razón de la consulta del principio del tutorial. Sin embargo, como no vas a trabajar sobre la tabla directamente, no es obligatorio que entiendas como funciona.

**Paso 3: Asigna el middleware necesario **

De nada sirve asignar los roles, si no nos ponemos juiciosos para que solos los usuarios correctos puedan acceder a los módulos correctos.
Debido a que esta es una característica nueva, probablemente la versión 1 no este preparada para soportarla, por tanto, la vamos a implementar en la versión 2
Lo primero que se debe hacer es decirle a la aplicación que va a utilizar el middleware de role, para eso, se edita el archivo app/Http/Kernel.php y se agrega en el arreglo de $middlewareAliases la siguiente línea:

‘role’ => \Spatie\Permission\Middlewares\RoleMiddleware::class

Finalmente, en la ruta de api_v2, se agrega el middleware de la siguiente forma
Route::get(‘recipes’, [RecipeController::class, ‘index’])->middleware([‘role:Administrator’]);

Es suuuper importante que el rol tenga el mismo nombre que el que definiste en el paso 2, ten en cuenta mayúsculas y trata de no usar tildes ni caracteres especiales

Paso 5: Realiza las pruebas end to end

Ingresamos como el usuario 1, que tiene rol de Administrator

Consultamos las recetas autenticados como le usuario 1

Nos autenticamos como el usuario 2

Intentamos realizar la consulta

Nos dice que no tenemos el rol adecuado para hacer la búsqueda

Paso 6: Realiza las pruebas unitarias

Dentro del directorio tests\Feature\Http\Controllers\Api\V2\RecipeTest.php que ya existe, vamos a crear comentar el test llamado test_index_v2, y vamos a crear dos nuevos test: test_get_recipies_by_administrator() y test_get_recipies_by_auditor() La estructura de los tests será la siguiente:

  1. Crear el rol por probar
  2. Actuar como un usuario con dicho rol
  3. Hacer una consulta a recipes
  4. Obtener el código http de respuesta

Este es mi código, pero, ya tu sabeh, el tuyo no tiene que ser exactamente igual al mio, lo que importa es que tengas claro la lógica

Finalmente, corre el test

Arreglemos entonces el test que habíamos comentado

`class RecipeTest extends TestCase
{
use RefreshDatabase;

  public function test_index_v2(): void
{
    // Crear un usuario con el rol de administrador
   $adminRole = Role::create(['name' => 'Administrator']);
   $user = User::factory()->create();
   $user->assignRole($adminRole);

   // Autenticar al usuario
   $this->actingAs($user);
    
    Category::factory()->create();

    $recipes = Recipe::factory(5)->create();

    $response = $this->getJson('/api/v2/recipes');
    $response->assertStatus(Response::HTTP_OK)
        ->assertJsonCount(5, 'data')
        ->assertJsonStructure([
            'data'  => [],
            'links' => [],
            'meta'  => [],
        ]);
    
} 

public function test_get_recipies_by_administrator(): void
{
   // Crear un usuario con el rol de administrador
   $adminRole = Role::create(['name' => 'Administrator']);
   $user = User::factory()->create();
   $user->assignRole($adminRole);

   // Autenticar al usuario
   $this->actingAs($user);

   // Acceder a una ruta protegida por el middleware 'role'
   $response = $this->get('/api/v2/recipes');

   // Verificar que la respuesta sea exitosa (código de estado 200)
   $response->assertStatus(200); 
    
   
}

public function test_get_recipies_by_auditor(): void
{
   // Crear un usuario con el rol de administrador
   $adminRole = Role::create(['name' => 'Auditor']);
   $user = User::factory()->create();
   $user->assignRole($adminRole);

   // Autenticar al usuario
   $this->actingAs($user);

   // Acceder a una ruta protegida por el middleware 'role'
   $response = $this->get('/api/v2/recipes');

   // Verificar que la respuesta sea no autorizada (código de estado 403)
   $response->assertStatus(403); 
    
   
}

}
`

Te dejo la tarea de implementar la lógica para que únicamente el Auditor pueda ver una única receta. Espero te haya gustado este tutorial.

Escribe tu comentario
+ 2
1
5200Puntos
un año

Lo revisareee, muchas gracias por tu aporte…