Políticas de acceso en Laravel 5.4 – Features del Framework

Las políticas de acceso te permitirán de una manera increíblemente fácil, limitar y bloquear el acceso a ciertas partes de la aplicación. Cuando programamos, parte de lo que realmente queremos, es que los métodos de nuestros controladores no sean mayores a las veinte (20) líneas y esto lo logramos aislando fragmentos de código en otros archivos, como por ejemplo validaciones, consultas, políticas y así.

Vamos a aprender en este tutorial cómo aislar el bloque de código respecto a las políticas de acceso.

¿Cuando usamos este feature?

Ejemplo: Un usuario ha creado los artículos con ID 1, 2 y 3, otro usuario ha creado los artículos con ID 4 y 5, entonces crearíamos una política de acceso para que cada usuario solo pueda editar y borrar sus artículos y no los de otro usuario.

Comencemos

Instala un proyecto “comencemos desde cero con un proyecto en blanco”, hazlo y vuelve para que a continuación creemos las tablas y así paso a paso cada archivo necesario para comprender completamente este feature.

Lo primero son las migraciones

Vamos a crear la migración POST php artisan make:model Post --migration  con este comando creamos el modelo y la migración de ese modelo, la de usuarios no la ejecutamos porque ya viene instalada en Laravel 🙂

Clase CreateUsersTable método up()

Clase CreatePostsTable método up()

Lo que sigue es tener datos para hacer pruebas (datos falsos o de semilla), para ello configuramos los seeds y factory.

Los seeders se crean con el siguiente comando, ejecuta ambos
php artisan make:seeder UserTableSeeder
php artisan make:seeder PostTableSeeder

Rimorsoft/database/seeds/UsersTableSeeder.php

Rimorsoft/database/seeds/PostsTableSeeder.php

Rimorsoft/database/factories/ModelFactory.php

Esto ya lo sabías 🙂 lo siguiente que debes hacer ahora es configurar los datos de la base de datos en el archivo .env  y ejecutar el comando php artisan migrate:refresh --seed

Ejemplo del archivo .env

¿Creamos la política de acceso?

A eso viniste, así que manos a la obra. Ejecuta el siguiente comando para crear el archivo de políticas de acceso. php artisan make:policy PostPolicy Recuerda que la idea es aislar y crear la lógica correspondiente.

Esto crea una carpeta y dentro el archivo correspondiente a la política de acceso

Rimorsoft/app/Policies/PostPolicy.php

Viene la parte donde damos de alta o hacemos saber que estos archivos existen, esto se hace dentro del ServiceProvider Rimorsoft/app/Providers/AuthServiceProvider.php

Esta es la configuración necesaria para hacer uso de las políticas de acceso, ahora lo que debemos hacer es el llamado de esta configuración donde queremos aplicarlo 🙂 vamos con el código, nota que vamos a configurar los métodos edit y destroy.

Como puedes observar, usamos esta línea de código $this->authorize('pass', $post);  donde pass es el método (y puede llevar cualquier nombre) en el archivo de políticas y $post representa a la entidad.

Lo que nadie te dice es que debes crear una vista llamada 403.blade.php  dentro de la carpeta errors, y cuando esta condición no se cumpla el sistema mostrará esta vista, donde curiosamente siempre escribo “PARECE QUE HACES TRAMPA… XD”

Con esto podemos concluir

Las políticas de acceso de tu sistema forman parte de la lógica natural; lógica que debemos hacer según la necesidad real, sin embargo, hay cosas comunes como el ejemplo planteado en este tutorial, entonces, en esos casos ¿por qué no hacerlo usando las políticas de acceso de Laravel? ademas nos ayuda con el orden y buenas practicas.

¿Qué te pareció? Haz la practica y coméntame como te fue con eso.

Comparte este artículo

Entra en la discusión y deja tu comentario

  • Proyecto Tau

    Hola. Muy interesante el ejemplo !!!

    Sugerencias:
    1. No sería mejor poner la verificación $this->authorize(‘pass’, $post); en un middleware ?
    2. Para los casos en los que la política sea gestionada de forma dinámica por un administrador, en lugar de simplemente return $user->id == $post->user_id; iria a buscar en la BD si existe o no allí esa relación
    Un cordial saludo !!!!!!

    • IsraelOrtuno

      Se podría incluir en un middleware pero esto no deja de ser un ejemplo. En un caso más práctico, normalmente tendríamos varias políticas diferentes como:
      create, edit, ...

      Para usarlas en Middlewares está:

      Route::put(‘/post/{post}’, function (Post $post) {
      // The current user may update the post…
      })->middleware(‘can:update,post’);

      Pero de este modo perdemos la opción de poder capturar la respuesta a una desautorización de acceso.

    • Gracias por tu comentario, lo que podría agregar es que hay muchas formas de lograr esto 🙂

      Sin embargo: Una política de acceso solo retorna true o false, y si el caso de false entonces responde con un 403 (prohibido)

      Los midleware podrían ser configurado para retornar cualquier error, se pueden hacer ahí cosas mas complejas.

      • User X

        Que buena publicación, y los comentarios me ayudaron a entender un poco más los casos de uso de las políticas de acceso vs middlewares (y)

        • Muchas gracias por tu comentario, luego escribo sobre middleware 🙂

  • Rodrigo

    Un gran ejemplo, gracias!, me podrían aclarar una duda por favor, el parámetro $user se pasa de manera automática?, y si no hay usuario logueado que sucede, gracias de antemano

    • IsraelOrtuno

      @disqus_p1h37IUePP:disqus sí, el User lo inyecta Laravel automáticamente

      • Rodrigo

        Muchas Gracias!!

    • Solo aplica si se está logueado, es una política de acceso para que solo los creadores puedan editar sus artículos y no los de otros…

  • Matias Candia

    que pasa si ademas de solo poder editar o eliminar los post q yo creo, tambien sea solo yo el q pueda verlos.. sirve esta politica para lograr eso? o como lo harian? estoy intentando hacer el admin de un sistema y quiero implementar algo asi..algo asi como el admin de wordpress donde el q se crea su cuenta de wordpress puede ver solo su panel de administracion.. lo que hice hasta ahora es el login de laravel , cree varios roles y le di permisos de vistas en un middleware, dentro del sistema creo un post pero si hago logout y luego login con otro usuario veo ese post creado en la lista.. ahi ya me pierdo..jj soy novato en esto.. cualquier duda o sugerencia es bienvenida.. muchas gracias..

    • Es fácil…. Es lo mismo y de hecho no tienes que hacer nada más 🙂
      Vas a listar solo tus post, algo así Post::where(‘user_id’, Auth::user()->id)->get();

      Eso consulta solo tus post y luego listarías, pero si alguien quiere ser astuto y cambia la url, el sistema dispara el error 403 con el mensaje “Parece que haces trampa XD”.

Veces