> Manuales > Manual del desarrollo de API con Laravel

Cómo configurar Laravel Fortify y personalizar su comportamiento para que funcione de la manera adecuada para el desarrollo de un API. Resolver problemas comunes de configuración de Fortify.

Configuración de Laravel Fortify

En los anteriores artículos del Manual de desarrollo de un API con Laravel Sanctum y Fortify hemos avanzado bastante en la realización del sistema de autenticación. Después de haber conocido e instalado en el artículo anterior Laravel Fortify, ahora tenemos que realizar algunas tareas de adaptación de Fortify según las necesidades de nuestro proyecto.

Las necesidades de nuestro proyecto vienen marcadas porque vamos a usar Fortify en el contexto de un API. Recuerda que Fortify no necesita necesariamente funcionar en un API, por lo que hay algunas configuraciones de casa que están más pensadas para sitios web. Tendremos que cambiarlas como verás a continuación y, de paso, nos dará pie a aprender algunas cosas más sobre este package de Laravel.

Configurar las funcionalidades de Fortify

En este paso vamos a editar el archivo de configuración del propio Fortify: config/fortify.php. En él encontramos un array llamado "features", el cual podemos activar o desactivar aquellas que nos interesen o no.

Si queremos las funcionalidades básicas de un sistema de autenticación, podríamos dejar algo así.

'features' => [
        Features::registration(),
        Features::resetPasswords(),
        Features::emailVerification(),
        // Features::updateProfileInformation(),
        // Features::updatePasswords(),
        // Features::twoFactorAuthentication([
        //     'confirm' => true,
        //     'confirmPassword' => true,
        //     // 'window' => 0,
        // ]),
],

No te preocupes porque hayamos dejado de lado algunas de las funcionalidades ofrecidas por Fortfy. Las que no hemos activado todavía se podrían activar más adelante si fuera necesario.

Desactivar las vistas

Para el uso que vamos a hacer de nuestro backend necesitamos desactivar las vistas de la aplicación para lo que respecta a Fortify. Esto lo realizamos también mediante el archivo de configuración de Fortify. Dentro del archivo config/fortify.php también buscamos el siguiente valor:

'views' => true,

Y lo cambiamos por

'views' => false,

En este punto es relevante comentar que la vista del "reset de la clave" si que la necesitaremos cuando activemos esa funcionalidad. La tendremos que activar manualmente en los archivos de rutas de nuestro proyecto backend con Laravel.

Este punto requiere más explicaciones para dejar claro cómo activar estas vistas. De todos modos, vamos a aplazar estas explicaciones más adelante cuando abordemos el flujo para recordar la clave.

Comportamiento de redirección si estás autenticado

Hay otra cosa que resulta molesta del comportamiento de Fortify, en el caso de querer usar el sistema como un servicio web (API). Se trata de la redirección a la ruta "/home" que se realiza cuando el usuario está autenticado e intenta hacer de nuevo un login.

Este comportamiento se debe a un middleware llamado RedirectIfAuthenticated, que está en la ruta app/Http/Middleware/RedirectIfAuthenticated.php.

Su código lo vamos a cambiar para que incluya este otro comportamiento, que permite detectar si estamos accediendo mediante Ajax a la ruta de login y, en caso que sea así, se envíe una respuesta en formato JSON.

El código que tenemos que añadir es este:

if ($request->expectsJson()) {
             return response()->json(['error' => 'Ya estás autenticado.'], 200);
}

El método $request->expectsJson() devuelve true cuando se esté invocando el login desde una solicitud Ajax.

Esa comprobación la tenemos que poner dentro del bucle foreach, donde ahora el código quedará de esta manera.

foreach ($guards as $guard) {
       if (Auth::guard($guard)->check()) {
           if ($request->expectsJson()) {
             return response()->json(['error' => 'Ya estás autenticado.'], 200);
           }
           return redirect(RouteServiceProvider::HOME);
      }
}

Básicamente, lo que hemos hecho es que se envíe un mensaje indicando que ya tienes el usuario autenticado, por lo que no necesitarías acceder de nuevo a la ruta de login.

Este comportamiento lo podrías redefinir para que tu API devuelva la respuesta que tú necesites, con el código HTTP que te resulte adecuado.

Comportamiento si no estás autenticado

El middleware Authenticate, en la ruta app/Http/Middleware/Authenticate.php también sería interesante cambiarlo. Básicamente este middleware realiza el trabajo de enviar al usuario a la ruta donde debería hacer su autenticación, para cada ruta que configuremos que requiera estar logueado.

Vamos a cambiarlo para que redirija a la ruta del frontend donde se hace el login.

En principio tenemos este código.

protected function redirectTo(Request $request): ?string
{
    return $request->expectsJson() ? null : route('login');
}

Podemos cambiarlo por este otro.

protected function redirectTo(Request $request): ?string
{
    if (!$request->expectsJson()) {
        return url(env('FRONTEND_URL') . '/login');
    }
    return null;
}

Si te fijas, estamos usando una variable de entorno nueva, por lo que necesitarás crearla en el archivo .env. La variable de entorno FRONTEND_URL deberá tener la ruta donde tienes la aplicación frontend.

El valor de la variable de entorno podría ser algo como esto:

FRONTEND_URL=http://localhost:8000

Problemas comunes de la configuración de Laravel Fortify

Ahora voy a señalar algunos problemas comunes que he encontrado a la hora de dar estos primeros pasos en la configuración de Laravel Fortify, con sus soluciones.

Solucionar 401 (Unauthorized) en Fortify

Durante el proceso de creación de tu sistema de login puedes apreciar un mensaje 401 (Unauthorized) cuando intentas acceder a una ruta para la cual necesitas estar autenticado.

Esta no debería ser la respuesta que el API te debería entregar, en el caso que ya hayas hecho login. Si has verificado que tu sesión está activa, porque hayas hecho un registro o login satisfactorio y aún así sigues recibiendo este mensaje puede deberse a dos motivos:

  1. Qué el dominio de tu frontend, desde donde estás haciendo la solicitud no esté entre los que se permite el inicio de sesión con variables de sesión. Entonces debes de asegurarte que la variable de entorno SANCTUM_STATEFUL_DOMAINScontiene un valor correcto. Atención en este punto poque debemos colocar el valor sin http://, que es uno de los errores típicos que pueden suceder. El valor es simplemente el nombre del dominio y el puerto, si es que estás usando un puerto personalizado. Por ejemplo: SANCTUM_STATEFUL_DOMAINS=localhost:8000
  2. Que no se estén creando las variables de sesión en el backend de manera correcta. En este caso debes asegurarte que no tienes la variable de sesión SESSION_DOMAIN en tu archivo .env. O, en el caso de tenerla, que contenga el dominio de tu backend, sin http:// o https://. Por ejemplo para desarrollo sería algo así SESSION_DOMAIN=localhost.

Solucionar has been blocked by CORS policy

Otro problema típico que te puede ocurrir es que las solicitudes se bloqueen por la política de CORS. En estos casos el acceso a las rutas te pueden entregar mensaje como este:

Access to XMLHttpRequest at 'http://localhost/sanctum/csrf-cookie' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Para solucionar este problema verifica:

El valor de allowed_origins podría estar definido, por ejemplo, de la siguiente manera:

'allowed_origins' => ['http://localhost:8000', 'https://escuela.it']
.
Podrías tener una variable de entorno para definir la URL de tu SPA y usarla en este punto.

Conclusión a la configuración básica de Laravel Fortify

Hasta aquí hemos podido terminar la configuración de nuestro backend para que pueda realizarse la autenticación de usuarios, usando los packages oficiales de Laravel Sanctum y Laravel Fortify.

Por supuesto, estarás deseando probar tu backend y realizar las tareas de autenticación con él, para verificar que todo está funcionando correctamente. Para realizar esta tarea no podríamos utilizar directamente con el navegador, porque las solicitudes deben realizarse mediante Ajax, además de enviar los datos correctos al backend para realizar el registro, autenticación y autorización. Por ello en el próximo artículo vamos a detenernos para mostrar un medio de ejercitar nuestra API y mandar las solicitudes necesarias para ponerla en marcha.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual