Laravel + Voyager + API para SPA

Laravel + Voyager + API para SPA

Últimamente estoy siguiendo un curso de Laravel en Ademass que me esta resultando muy útil para entender el funcionamiento interno de este framework que vengo utilizando en el trabajo hace ya un tiempo.

El problema con utilizarlo solo en el trabajo es que, si algo ya funciona, no me detengo a entenderlo en su totalidad ya que eso insumiría mucho más tiempo del necesario para cumplir con la tarea que tengo asignada en ese momento.

Uno de estos temas es la autenticación de SPAs en Laravel para acceder a su API de forma segura. Existe passport que permite implementar OAuth2 y es el acercamiento más completo y seguro pero para comenzar decidí hacerlo con sanctum que es un acercamiento más sencillo al problema. Solo debemos recordar que en este caso tanto el frontend como el backend deben estar en el mismo dominio.

Hacerlo con Laravel breeze es sencillo y pude tenerlo funcionando con Postman en unas horas de pruebas.

Para entender un poco más el funcionamiento decidí incorporar Voyager, una interfaz de administración completa para Laravel que además permite crear CRUDs de manera visual (agregando tablas a la base de dato, configurando cada campo, etc.).

Pero entonces no puedo depender de Breeze para autoconfigurar todo lo necesario para la autenticación, además de que no tengo disponibles los endpoinst para los CRUDs creados con Voyager.

Estos son los pasos que realice para tener todo integrado y funcionando:

Instalar Laravel

composer create-project laravel/laravel "voyagerapi" 10.*
cd "voyagerapi"

Configurar la base de datos

Crea la base de datos «voyagerapi» (generalmente MySql). Abre el archivo .env y configura los datos de acceso a la misma:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=voyagerapi
DB_USERNAME=root
DB_PASSWORD=pass

Instalar Voyager

composer require tcg/voyager
php artisan voyager:install --with-dummy

Ya deberías poder correr php artisan serve y acceder a localhost:8000/admin pues Voyager corre las migración al instalarse. Si encuentras algún problema puedes correr php artisan migrate para asegurarte.

Debemos ejecutar npm i para instalar paquetes de front.

Puedes acceder con email: [email protected] password: password. Mas información en la documentación de Voyager.

Aquí hay que jugar un rato con Voyager para entender como funciona y luego proseguir.

Para que funcione correctamente la creación de modelos al crear nuevas tablas debes modificar el siguiente archivo y agregar este contenido:

config/voyager.php
    'models' => [
        'namespace' => 'App\\Models\\',
    ],

Soporte para APIs y Documentación de Apis

Usando el paquete joy-voyager-api podremos agregar soporte para REST Api con Passport y Swagger para la documentación a Voyager. En este caso no usaremos Passport pero si las demás características.

composer require joy/voyager-api -W
php artisan vendor:publish --provider="Joy\VoyagerApi\VoyagerApiServiceProvider" --force

-W se usa para permitir cambiar la versión de un paquete fijado en composer.lock, de otra forma no podremos instalar el paquete.

Ahora debemos agregar/modificar las siguientes variables de entorno en el archivo .env:

APP_URL=http://localhost:8000 #la URL de tu backend/app laravel
FRONTEND_URL=http://localhost:3000 #la URL de tu front/SPA de react, vue, etc
SESSION_DOMAIN=localhost #el dominio donde reciden los dos back y front (debe ser el mismo dominio)
L5_SWAGGER_CONST_HOST="${APP_URL}"
L5_SWAGGER_CONST_HOST2="${FRONTEND_URL}"

Modificaciones para usar Sanctum

Ahora debemos modificar manualmente contenido en diferentes archivos del proyecto para usar Sanctum:

Http/Kernel.php
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [           \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

config/auth.php
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'sanctum',
            'provider' => 'users',
        ],
    ],

Por último deberemos ejecutar estos comandos para finalizar la instalación:

npm i

php artisan migrate

php artisan joy-voyager-api:l5-swagger:generate

El último comando publica la documentación de tu api en http://localhost:8000/api/documentation

Acceder al API

Todas las rutas API generadas por Voyager están protegidas detrás del acceso de usuario (excepto el login claro). Podría crearse un usuario por defecto de FrontEnd, con su propio rol y permisos para las rutas que queremos sean totalmente públicas y autenticarlo automáticamente al ingresar al sitio.

Para usuarios con más permisos, debemos mostrar al usuario un formulario de login, y realizar las siguientes acciones para poder acceder con usuario y contraseña al api desde un SPA:

  1. Hacer una petición GET a http://localhost:8000/sanctum/csrf-cookie para obtener la cookie csrf: XSRF-TOKEN.
  2. Incluir la cookie csrf en cada petición a partir de ese momento en el encabezado X-XSRF-TOKEN.
  3. Hacer una petición a /admin/login con los datos de acceso del usuario a autenticar en el frontend. Puedes crear usuarios en voyager sin el permiso para ingresar a la administración y agregándole los permisos que necesites para leer/modificar/eliminar los recursos necesarios para que el frontend funcione.

A partir de este momento el usuario está autenticado y puede acceder a los recursos que le corresponda a su rol de voyager en el api.

Repositorio de github: https://github.com/ivanromeroprog/base-laravel-voyager-api

1 COMENTARIO

Deja una respuesta

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