Laravel: Uso de Policy y Gates

Policy y Gates

En Laravel, la autorización de usuarios se maneja principalmente a través de Policies y Gates. Ambos conceptos son fundamentales para controlar el acceso a los recursos y acciones dentro de la aplicación. Mientras que las Policies están diseñadas para manejar la autorización basada en modelos específicos, las Gates ofrecen una manera más simple y generalizada de definir la lógica de autorización para cualquier acción dentro de la aplicación. Comprender cómo y cuándo usar cada uno de estos mecanismos es clave para implementar un sistema de autorización robusto y flexible.

¿Para qué sirve?

Policies y Gates en Laravel sirven para definir reglas de autorización, pero cada una tiene su propio ámbito de aplicación:

  • Policies: Están orientadas a la autorización en torno a un modelo específico. Se utilizan para verificar si un usuario puede realizar ciertas acciones (como ver, crear, actualizar o eliminar) en un modelo en particular.
  • Gates: Proporcionan una forma más sencilla y flexible de definir la autorización para acciones que no necesariamente están vinculadas a un modelo. Los Gates son ideales para situaciones donde se necesita verificar permisos para operaciones generales o globales dentro de la aplicación.

Creación y Uso de Policies

Paso 1: Crear una Policy

Para crear una Policy en Laravel, se utiliza el comando Artisan:

php artisan make:policy PostPolicy --model=Post

Esto generará una clase PostPolicy en app/Policies, que contendrá métodos para las diferentes acciones que se pueden realizar en un Post (ver, crear, actualizar, eliminar, etc.).

Paso 2: Definir las Reglas en la Policy

Dentro de la clase PostPolicy, se define la lógica de autorización para cada acción:

namespace App\Policies;

use App\Models\User;
use App\Models\Post;

class PostPolicy
{
    public function view(User $user, Post $post)
    {
        return $post->is_public || $user->id === $post->author_id;
    }

    public function create(User $user)
    {
        return $user !== null;
    }

    public function update(User $user, Post $post)
    {
        return $user->id === $post->author_id;
    }

    public function delete(User $user, Post $post)
    {
        return $user->id === $post->author_id;
    }
}

Paso 3: Registrar la Policy

Para que Laravel sepa usar la Policy, es necesario registrarla en AuthServiceProvider:

protected $policies = [
    Post::class => PostPolicy::class,
];

Paso 4: Usar la Policy

La Policy puede ser utilizada en los controladores para autorizar acciones:

public function update(Request $request, Post $post)
{
    $this->authorize('update', $post);

    $post->update($request->all());
    return redirect()->route('posts.index')->with('success', 'Post actualizado con éxito.');
}

Creación y Uso de Gates

Paso 1: Definir un Gate

Los Gates se definen en el AuthServiceProvider, dentro del método boot. Por ejemplo, para definir un Gate que controle si un usuario puede realizar una acción administrativa:

use Illuminate\Support\Facades\Gate;

public function boot()
{
    $this->registerPolicies();

    Gate::define('admin-actions', function (User $user) {
        return $user->is_admin;
    });
}

Paso 2: Usar un Gate

Los Gates pueden ser utilizados en cualquier parte de la aplicación:

  • En los controladores:
public function performAdminAction()
{
    if (Gate::allows('admin-actions')) {
        // Lógica para la acción de administrador
    } else {
        abort(403);
    }
}
  • En vistas Blade:
@can('admin-actions')
    <button>Acción de Administrador</button>
@endcan

¿Cuándo usar Policies vs Gates?

  • Usa Policies cuando estás manejando autorización relacionada con modelos específicos. Son ideales para controlar el acceso a recursos particulares como posts, usuarios, productos, etc.
  • Usa Gates cuando necesitas una autorización más genérica que no esté ligada a un modelo en particular. Son útiles para verificar permisos globales, como verificar si un usuario es administrador, o permitir acciones específicas que no dependen de un modelo.

Ejemplo práctico combinando Policies y Gates

Supongamos que tienes un blog y deseas controlar el acceso tanto a nivel de post (con Policies) como a nivel global para tareas administrativas (con Gates).

Paso 1: Definir la Policy para los Posts

class PostPolicy
{
    public function update(User $user, Post $post)
    {
        return $user->id === $post->author_id;
    }

    public function delete(User $user, Post $post)
    {
        return $user->id === $post->author_id || $user->is_admin;
    }
}

Paso 2: Definir el Gate para Acciones Administrativas

Gate::define('admin-actions', function (User $user) {
    return $user->is_admin;
});

Paso 3: Usar ambos en el controlador

public function delete(Post $post)
{
    $this->authorize('delete', $post); // Policy para autorización basada en modelo

    if (Gate::denies('admin-actions')) {
        abort(403, 'No tienes permiso para realizar esta acción.');
    }

    $post->delete();
    return redirect()->route('posts.index')->with('success', 'Post eliminado con éxito.');
}

Conclusión

Las Policies y Gates son herramientas complementarias en Laravel que te permiten manejar la autorización de manera clara y estructurada. Las Policies te ofrecen un control detallado y específico sobre los modelos, mientras que los Gates proporcionan flexibilidad para manejar permisos globales o independientes de los modelos. Al combinarlas, puedes implementar un sistema de autorización robusto que cubra tanto necesidades específicas como generales dentro de tu aplicación.

Un comentario

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *