Mascotas Perdidas Py – Parte II

17 de enero

Siempre que leo las diferentes formas de autenticar con Laravel, termino yendo al que mejor entiendo, pero también uno un chiqui complicado: Fortify

¿Por qué? No hay porque…

Hablemos un poquito de Fortify

Fortify es un sistema que se usa en el backend (tras bambalinas) de autenticación agnóstico al frontend (eso significa que el registra las rutas para los diferentes procesos: login, registro, cambio de contraseña y verificación de la cuenta) y nosotros debemos de programar las diferentes interfaces, que es algo que a mi me gusta, porque nos da flexibilidad aunque a costa de un poco más de trabajo.

Antes de seguir, voy a crear una nueva rama para el proyecto de modo a que todo lo relacionado con autenticación y registro esté en ella y esté disponible más adelante para ser revisado por ustedes.

git checkout -b fortify-auth

Bueno, continuemos, primero tenemos que incluir fortify a nuestro proyecto, eso lo hacemos ejecutando:

composer require laravel/fortify

Esto incluira en nuestro achivo composer.json los datos de la ultima version estable de fortify, y la instalará en nuestra carpeta vendor, por detrás se ejecutará un comando llamado composer dump-autoload que lo agrega en el contexto de laravel y así ser visible en el proyecto.

Deja una salida similar a esta si es que todo está ok.

Info from https://repo.packagist.org: #StandWithUkraine
Using version ^1.16 for laravel/fortify
./composer.json has been updated
Running composer update laravel/fortify
Loading composer repositories with package information
Info from https://repo.packagist.org: #StandWithUkraine
Updating dependencies
Lock file operations: 5 installs, 0 updates, 0 removals
  - Locking bacon/bacon-qr-code (2.0.8)
  - Locking dasprid/enum (1.0.3)
  - Locking laravel/fortify (v1.16.0)
  - Locking paragonie/constant_time_encoding (v2.6.3)
  - Locking pragmarx/google2fa (v8.0.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 5 installs, 0 updates, 0 removals
  - Downloading bacon/bacon-qr-code (2.0.8)
  - Downloading laravel/fortify (v1.16.0)
  - Installing dasprid/enum (1.0.3): Extracting archive
  - Installing paragonie/constant_time_encoding (v2.6.3): Extracting archive
  - Installing pragmarx/google2fa (v8.0.1): Extracting archive
  - Installing bacon/bacon-qr-code (2.0.8): Extracting archive
  - Installing laravel/fortify (v1.16.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   INFO  Discovering packages.  

  laravel/fortify ................................................. DONE
  laravel/sail .................................................... DONE
  laravel/sanctum ................................................. DONE
  laravel/tinker .................................................. DONE
  nesbot/carbon ................................................... DONE
  nunomaduro/collision ............................................ DONE
  nunomaduro/termwind ............................................. DONE
  spatie/laravel-ignition ......................................... DONE

80 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force

   INFO  No publishable resources for tag [laravel-assets].

Listo, con esto ya podemos hacer uso del backend de autenticación que nos disponibiliza Fortify. Una forma de chequear esto es ejecutando:

php artisan route:list
En esta vemos resaltadas todas las rutas que fortify genera para nosotros, como login, register, etc…

Con esto podemos apreciar todas las rutas disponibles en el sistema actualmente.

Luego procedemos a publicar los recursos que Fortify tiene en vendor (recordar que los recursos mientras estan en vendor, no van a ser modificables por nosotros, o por lo menos no entrarán en el versionado que manejamos, por eso se extraen del vendor y se colocan dentro de nuestras carpetas) ejecutando el comando:

php artisan vendor:publish \
--provider="Laravel\Fortify\FortifyServiceProvider"

Alli podemos ver que se publican las acciones (la mayoría son reglas de validaciones para registro y/o cambio de password); el FortifyServiceProvider que registra esas acciones en el inicio (boot) del sistema; y las migracion que agrega la tabla para tener autenticación en dos pasos disponible.

Ahora correremos las migraciones, que de hecho las tenemos pendiente desde la entrada anterior, y se crearan las tablas: users, password_resets, personal_access_token, y dos tablas mas que son con las que laravel controla las migraciones ejecutadas: migrations y failed_jobs.

Luego agregamos la siguiente linea al archivo config/app.php para registrar las acciones de fortify en el sistema, específicamente en el array de providers

App\Providers\FortifyServiceProvider::class

Luego procedemos a modificar el archivo config/fortify.php, y vamos a la sección de features (características) y solo dejaremos activadas las de registro, cambio de password y verificación de emails.

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

A continuación tenemos que indicar a Fortify, cual sera nuestra vista para login (que aparte debemos crearla, pero les mostraré un recurso que nos será útil) para ello editamos el archivo app/Providers/FortifyServiceProvider.php

en el método boot agregamos el código:

    public function boot(): void
    {
        Fortify::loginView(function () {
            return view('auth.login');
        });
        //...

Con esto Fortify ira a la vista login.blade.php que estará dentro de la carpeta auth.

Luego de esa entrada agregamos las siguientes que necesitamos para registrar usuarios, el formulario de me olvide mi contraseña, el formulario para cambiar de contraseña, y la vista que muestra el mensaje de que necesitamos verificar la cuenta para continuar.

        //...
        Fortify::registerView(function () {
            return view('auth.register');
        });

        Fortify::requestPasswordResetLinkView(function () {
            return view('auth.forgot-password');
        });

        Fortify::resetPasswordView(function ($request) {
            return view('auth.reset-password', ['request' => $request]);
        });

        Fortify::verifyEmailView(function () {
            return view('auth.verify-email');
        });
        //...

Con eso listo ya instruimos a Fortify cuales seran nuestras vistas, ahora continuaremos con la modificacion de nuestro modelo de Users, para indicarle que debe implementar las funcionalidades de verificacion de email, para ellos descomentamos la linea (o agregamos si no está)

use Illuminate\Contracts\Auth\MustVerifyEmail;

y también le decimos que agregue el trait de MustVerify email

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable, /* Esta -> */ MustVerifyEmail;

Por hoy eso es todo, procedemos a agregar al repositorio todos los archivos creados y modificados:

git add app/Actions/ app/Providers/FortifyServiceProvider.php config/fortify.php database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php package-lock.json

git commit -a -m "Fortify Auth functionality added \
Fortify features enabled and respective view names assigned"

git push --set-upstream origin fortify-auth

En la siguiente entrada les mostraré como son nuestras vistas para login, registro y reset de password usando Fortify y probaremos que tal funcionan.