Autorización con Lumen (Laravel): Gates, qué son y cómo usarlas

Cómo usar Gates en Lumen para restringir el acceso de usuarios con roles específicos a ciertas acciones de tu API.

  • laravel
  • php
  • backend
Ilustración para el artículo sobre autorización con Gates en Lumen y Laravel

Laravel proporciona dos formas principales de autorizar acciones: Gates (puertas) y Policies (políticas). La idea es sencilla: las puertas proporcionan un enfoque simple basado en closures, mientras que las políticas agrupan la lógica en torno a un modelo o recurso concreto. En este artículo vemos un ejemplo usando Lumen para crear y aplicar un Gate.

Usar esto en tu proyecto es muy útil cuando tienes diferentes tipos de usuarios con roles específicos y necesitas restringir el acceso a ciertas acciones.

Gates

Definición

Un ejemplo sencillo de Gate se define en App\Providers\AuthServiceProvider:

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;

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

    Gate::define('update-post', function (User $user, Post $post) {
        return $user->id === $post->user_id;
    });
}

En mi caso la autenticación de usuarios se hace de manera “manual”, así que lo defino directamente en el AuthServiceProvider:

public function boot()
{
    Auth::viaRequest('custom-token', function (Request $request) {
        return Users::where('user_token', $request->bearerToken())->first();
    });

    Gate::define('index', function ($user_id, $section_id) {
        return Sections::where('user_id', $user_id)->where('section_id', $section_id)->count() > 0
            ? Response::allow()
            : Response::deny("You don't have permission on this section");
    });
}

Uso en Controlador

De esta manera ya puedo definir tantas acciones autorizadas como necesite (show, create, edit, destroy, etc.), y luego en el controlador hago algo así:

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;

class SectionController extends Controller
{
    public function index(Request $request)
    {
        if (!Gate::allows('index', $request->section_id))
            return response()->json(['error' => 'Unauthorized'], 401);

        // If User Authorized ...
    }
}

Artículo creado a partir de la documentación oficial de Laravel.