Header Ads Widget

Ticker

6/recent/ticker-posts

Establecer permisos con objetos de política

 Establecer permisos con objetos de política

Podríamos haber creado un problema al permitir que cualquier usuario del sistema elimine cualquier hilo del sistema. Sería mejor si un usuario registrado solo pudiera eliminar los hilos que él o ella creó. Este tutorial verá cómo podemos asignar permisos a los usuarios en el sistema que decidirán si están autorizados o no para realizar una acción como eliminar un hilo. Primero veremos cómo completar esta tarea a mano, por así decirlo, y luego veremos la creación de un objeto de política dedicado en su lugar para agilizar el proceso.


Sin políticas, los usuarios pueden tener demasiado poder

En el último tutorial, brindamos a los usuarios la posibilidad de eliminar cualquier hilo que hayan creado. Bueno, resulta que un usuario no solo puede eliminar sus propios hilos, sino que también puede eliminar cualquier hilo del sistema, sin importar quién lo haya creado. Seguramente no queremos que este sea el caso, por lo que tendremos que considerar cómo limitar los poderes de los usuarios individuales. Por ejemplo, si iniciamos sesión como Nikola Tesla, solo deberíamos poder eliminar sus hilos. Mira como Nikola sigue adelante y borra uno de los hilos de Tom. ¡No está bien!
el usuario tiene demasiados permisos


Refactorización de la clase CreateThreadsTest

A medida que comenzamos a agregar permisos para lo que un usuario puede y no puede hacer en el sitio, podemos comenzar con una prueba. No crearemos una nueva prueba, sino que refactorizaremos una que ya tenemos. Ya hay una prueba de test_guests_can_not_delete_threads () en la clase. Esta prueba asegura que un usuario que no haya iniciado sesión no pueda eliminar un hilo. Ahora pensemos en eso por un segundo. No solo no queremos que los invitados del sitio eliminen los hilos, también no queremos que los usuarios registrados eliminen los hilos de otras personas. Así que cambiaremos esta prueba a test_unauthorized_users_can_not_delete_threads (). Esto refleja el hecho de que queremos protegernos de los invitados, así como de los usuarios autenticados que no tienen los permisos necesarios.

Con estos pensamientos en mente, aquí hay una maqueta aproximada de esa prueba.

Por supuesto, no se inicia, pero actualizaremos el código a medida que avanzamos para solucionarlo.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_unauthorized_users_can_not_delete_threads
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

F 1/1 (100%)

Tiempo: 892 ms, memoria: 10,00 MB

Hubo 1 falla:

1) Pruebas \ Característica \ CreateThreadsTest :: test_unauthorized_users_can_not_delete_threads
No se pudo afirmar que dos cadenas son iguales.
--- Esperado
+++ Real
@@ @@
-'http: // localhost / login '
+ 'http: // localhost / hilos'

/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:97
/home/vagrant/Code/forumio/tests/Feature/CreateThreadsTest.php:62

¡FALLOS!
Pruebas: 1, afirmaciones: 4, fallos: 1.

Uso de su propia lógica en destroy ()
La primera forma en que podemos abordar esto es poner en marcha nuestra propia lógica que verifica los permisos del usuario. Podemos hacer esto en el método destroy () de la clase ThreadsController. Resaltado en el fragmento a continuación, se muestra un poco de lógica que se puede colocar en el controlador para asegurarse de que si un usuario intenta eliminar un hilo que no es de su propiedad, no se le permitirá completar la función de eliminación .

Efectivamente, eso permite que la prueba pase.

vagrant @ homestead: ~ / Code / forumio $ phpunit --filter test_unauthorized_users_can_not_delete_threads
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

. 1/1 (100%)

Tiempo: 821 ms, memoria: 10,00 MB

OK (1 prueba, 4 afirmaciones)

Ahora podemos ejecutar el conjunto completo de pruebas y asegurarnos de que todo esté bien.

vagabundo @ homestead: ~ / Código / forumio $ phpunit
PHPUnit 6.5.5 por Sebastian Bergmann y colaboradores.

...... F ...................... 29/29 (100%)

Tiempo: 3,23 segundos, memoria: 12,00 MB

Hubo 1 falla:

1) Pruebas \ Característica \ CreateThreadsTest :: test_a_thread_can_be_deleted
Código de estado esperado 204 pero recibió 403.
No se pudo afirmar que lo falso es verdadero.

/home/vagrant/Code/forumio/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:78
/home/vagrant/Code/forumio/tests/Feature/CreateThreadsTest.php:74

¡FALLOS!
Pruebas: 29, afirmaciones: 50, fallos: 1.

UH oh. Parece que no todo está bien. La prueba test_a_thread_can_be_deleted () ahora está fallando. ¿Qué está pasando en esa prueba? Echemos un vistazo.

Esta prueba aquí es buena, pero estamos descubriendo que tal vez sea un poco generalizada a medida que comenzamos a desarrollar las cosas. Para solucionar este problema, podemos hacer que la prueba sea más específica, como test_authorized_users_can_delete_threads (). Además, necesitaremos corregir el código en la prueba para reflejar el hecho de que cuando un usuario está eliminando un hilo, su identificación de usuario debe coincidir con la identificación de usuario asociada con ese hilo. De lo contrario, eso significa que están intentando eliminar un hilo que no les pertenece, lo cual no podemos permitir. El código resaltado muestra dónde hacemos esta conexión explícita.

Ahora volvemos a todas las pruebas en un estado de aprobación, lo cual es bueno.
phpunit pasan todas las pruebas


Prueba en el navegador

Muy rápido, podemos probar esto en el navegador ahora. Iniciamos sesión como Nikola Tesla y si intentamos eliminar un hilo con el usuario asdf, se nos redirige inmediatamente y el hilo continúa existiendo en la base de datos. * No * se eliminó, que es lo que queremos.
sin permiso para borrar el modelo


Dejar caer el martillo

Ahora que lo pienso, tal vez redirigir al usuario sea demasiado agradable si está tratando de hacer algo que realmente no debería estar haciendo. Si ese es el caso, podemos soltar el martillo y simplemente abortar () la solicitud así.

Puede ver que el usuario recibe un buen golpe cuando intenta hacer algo nefasto ahora.
Symfony httpexception

Tenga en cuenta que si está utilizando este enfoque, debe actualizar la prueba correspondiente para asegurarse de que tenga en cuenta el código de estado 403. Esta actualización a continuación lo permite.

actualizar el método destroy () en threadsController
agregar lógica en destroy para manejar esto

arreglar las pruebas que ahora fallan


Mejores permisos con objetos de política

Así que tuvimos un problema con los usuarios que realizaban acciones que no deberían haber hecho. Al igual que los usuarios tienen permisos en un sistema operativo como Linux , también podemos asignar permisos a los usuarios en nuestra aplicación. Al principio tomamos la ruta larga y creamos una solución al problema a mano, por así decirlo. Ahora, usaremos un objeto de política dedicado para resolver más fácilmente nuestro problema. Un objeto de política es como la protección de un modelo. Determina los permisos. Como la mayoría de las funciones en Laravel, puedes usar artisan para crear el texto estándar para ti, lo cual es muy bueno. Crearemos el objeto de política ahora.

vagrant @ homestead: ~ / Code / forumio $ php artisan make: policy ThreadPolicy --model = Thread
Política creada con éxito.

Justo arriba, ingresamos el comando para crear nuestro nuevo objeto de política. También observe la bandera de –modelo. Aquí especificamos a qué modelo está asociada esta política. Al especificar esta bandera, obtienes todo este texto estándar aquí.

Tenga en cuenta que esta acción ha creado un nuevo directorio y archivo. Políticas es el directorio y ThreadPolicy.php es su archivo.
clase de objeto de política en laravel

Comenzaremos completando el método update () de la clase. Podemos configurar un escenario en el que el método verifica si la identificación del usuario de los hilos es igual a la identificación del usuario autenticado así:


Configuración de AuthServiceProvider

Ahora que tenemos un objeto de política dedicado, debe registrarse correctamente en la clase AuthServiceProvider. A continuación, simplemente comentamos la línea de código existente en la propiedad $ policies. Luego creamos un nuevo mapeo entre nuestro Thread Model y ThreadPolicy que hemos creado. También podríamos eliminar el código comentado, pero ayuda a demostrar cómo funciona el mapeo, así que lo dejaremos así.


Haciendo uso de autorizar () en el controlador

El trabajo preliminar y el texto estándar ya están listos para nosotros. Eso significa que podemos hacer uso del método authorize () asociado con un objeto de política en nuestro controlador. Por ejemplo, considere este código:

El código resaltado arriba se apoya en ese objeto de política que creamos para hacer su trabajo. Examina el método update () en ThreadPolicy y comprueba si la identificación del usuario del hilo y la identificación del usuario autenticado coinciden. Si coinciden, el usuario está autorizado a continuar. Si no coinciden, se lanza automáticamente una excepción no autorizada. Una vez más, podemos iniciar sesión en la aplicación como usuario de Nikola Tesla y cuando intentamos eliminar una publicación realizada por el usuario asdf, obtenemos esa excepción.
acceso denegado excepción http


Cómo utilizar la directiva @can blade

Con las políticas configuradas, ahora puede hacer uso de una directiva @can realmente genial en sus vistas de hoja si lo desea. Queremos hacer uso de la directiva @can para mostrar selectivamente el enlace de eliminación de hilo a los usuarios. En otras palabras, si el usuario no está autorizado para realizar una eliminación en el hilo dado, entonces no deberíamos mostrarle el enlace de eliminación del hilo. Así es como podemos actualizar la vista para manejar esto. En el archivo threads / show.blade.php, busque el enlace para eliminar hilo y envuélvalo en la directiva @can como se ve aquí:

Esto es tan hábil. El marcado dice, si el usuario que inició sesión está autorizado a 'actualizar' (recuerde el método que completamos) un $ hilo, luego muestre el enlace. Si no están autorizados, ese enlace no se mostrará.


El usuario que inició sesión no ve el enlace de eliminación para el hilo de otras personas

El usuario que inició sesión no ve el enlace de eliminación para el hilo de otras personas


El usuario que inició sesión ve el enlace de eliminación de su propio hilo

El usuario que inició sesión ve el enlace de eliminación de su propio hilo


Otorgar superpoderes de administrador

Mientras estamos en el tema de autorización, permisos y objetos de política, veamos cómo podemos otorgar poderes de administración a un usuario. En cualquier aplicación, debe haber un usuario que tenga la capacidad de administrar cosas con privilegios elevados. Por ejemplo, ¿cómo podemos hacer que Nikola Tesla sea el administrador? ¿Cómo puedes implementar esto?


Política específica antes del método ()

En cualquier clase de Política dada, puede crear un método before () que es una forma de otorgar autorización para todos los demás métodos basados ​​en un criterio dado. El siguiente fragmento le dará autorización a Nikola Tesla para todas las cosas en el objeto Política.

Dado que ahora le hemos otorgado poderes de súper administrador a Nikola, puede eliminar los hilos de otras personas.
los poderes de administrador pueden eliminar los hilos de otras personas


AuthServiceProvider Global

¿No quiere lidiar con la concesión de la autorización por política? No hay problema. En ese caso, visite AuthServiceProvider.php e invoque el método before () de la clase Gate.

Ahora, Nikola Tesla es un superusuario pase lo que pase.


Resumen de configuración de permisos con objetos de política

En este tutorial, tuvimos una buena introducción a la creación de clases de políticas en Laravel para ayudar a administrar los permisos de los usuarios en una aplicación. Los objetos de política funcionan en una relación uno a uno entre una clase de modelo determinada y una clase de política determinada. Una vez configurada la Política, podemos hacer uso de métodos simples en el controlador para determinar cuándo se deben tomar acciones o no. Además, aprendimos sobre esa directiva @can genial en las vistas de su hoja que puede mostrar elementos de la interfaz de usuario de forma selectiva según los permisos del usuario que inició sesión. ¡Fantástico!

Publicar un comentario

0 Comentarios