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

Los comentarios están cerrados.