Laravel Fortify, qué es, cuando usar y primeros pasos

Laravel Fortify es un paquete para la autenticación, registro, recuperación de contraseña, verificación de correo electrónico y más, en pocas palabras, permite realizar las mismas funcionalidades que Laravel Breeze que empleamos antes, pero la diferencia radica en que no es tan intrusivo, cuando instalamos laravel Breeze el mismo instala Tailwind.css y género varios componentes, controladores, vistas y rutas asociadas; en el caso de Laravel Fortify no es así y nos provee las mismas características pero sin necesidad de la interfaz gráfica, por lo tanto, es particularmente útil cuidando quieres desarrollar un backend de autenticación más personalizado que el que nos ofrece Breeze; es importante señalar a que si estás empleando Laravel Breeze o alguna solución similar no es necesario utilizar Laravel Fortify.

Otra posible comparación que pueda que estés realizando es con Sanctum, Laravel Fortify y Laravel Sanctum no son paquetes mutuamente excluyentes ni competidores si no, se pueden emplear en un mismo proyecto en caso de que se lo requiere, Laravel Sanctum solo se ocupa de administrar tokens API y autenticar a los usuarios existentes mediante cookies o tokens de sesión. Sanctum no proporciona ninguna ruta que maneje el registro de usuarios, el restablecimiento de contraseñas, etc, en pocas palabras Sanctum está enfocado en la autenticación de una Api Rest y Laravel Fortify para una aplicación web tradicional.

Instalación y configuración

Para instalar Laravel Fortify empleamos el siguiente comando:

$ composer require laravel/fortify

El siguiente paso es ejecutar el comando de instalación:

$ php artisan fortify:install

Este comando generará las migraciones, archivo de configuración, provide entre otros.

Ejecutamos las migraciones:

$ php artisan migrate

Y con esto, ya podemos emplear Laravel Fortify.

Características

Laravel Fortify cuenta con varias características que podemos habilitar o deshabilitar a gusto:

config\fortify.php

'features' => [
    Features::registration(),
    Features::resetPasswords(),
    Features::emailVerification(),
],

Las mismas permite des/habilitar la opción de registro, reiniciar la contraseña y verificación por emails respectivamente, en caso de que no quieras emplear alguna o varias de estas opciones, simplemente la debes de comentar, por ejemplo, si quieres desactivar la verificación por email:

'features' => [
    Features::registration(),
    Features::resetPasswords(),
    // Features::emailVerification(),
],

Para ejemplificar su uso, si hacemos un:

$ php artisan r:l

Veremos todas las rutas generadas por Fortify:

GET|HEAD  register ............................................ register › Laravel\Fortify › RegisteredUserController@create
  POST      register ........................................................ Laravel\Fortify › RegisteredUserController@store
  POST      reset-password ................................... password.update › Laravel\Fortify › NewPasswordController@store
  GET|HEAD  reset-password/{token} ........................... password.reset › Laravel\Fortify › NewPasswordController@create
  GET|HEAD  two-factor-challenge ......... two-factor.login › Laravel\Fortify › TwoFactorAuthenticatedSessionController@create
  POST      two-factor-challenge ............................. Laravel\Fortify › TwoFactorAuthenticatedSessionController@store
  GET|HEAD  up ............................................................................................................... 
  GET|HEAD  user/confirm-password ....................................... Laravel\Fortify › ConfirmablePasswordController@show
  POST      user/confirm-password ................... password.confirm › Laravel\Fortify › ConfirmablePasswordController@store
  GET|HEAD  user/confirmed-password-status .. password.confirmation › Laravel\Fortify › ConfirmedPasswordStatusController@show
  POST      user/confirmed-two-factor-authentication two-factor.confirm › Laravel\Fortify › ConfirmedTwoFactorAuthenticationC…  
  PUT       user/password ................................. user-password.update › Laravel\Fortify › PasswordController@update  
  PUT       user/profile-information . user-profile-information.update › Laravel\Fortify › ProfileInformationController@update  
  POST      user/two-factor-authentication ..... two-factor.enable › Laravel\Fortify › TwoFactorAuthenticationController@store  
  DELETE    user/two-factor-authentication .. two-factor.disable › Laravel\Fortify › TwoFactorAuthenticationController@destroy  
  GET|HEAD  user/two-factor-qr-code .................... two-factor.qr-code › Laravel\Fortify › TwoFactorQrCodeController@show
  GET|HEAD  user/two-factor-recovery-codes ........ two-factor.recovery-codes › Laravel\Fortify › RecoveryCodeController@index
  POST      user/two-factor-recovery-codes .................................... Laravel\Fortify › RecoveryCodeController@store
  GET|HEAD  user/two-factor-secret-key ........... two-factor.secret-key › Laravel\Fortify › TwoFactorSecretKeyController@show

Si ingresamos a la de login, veremos un error como el siguiente:

http://larafirstepspackages.test/login

Target [Laravel\Fortify\Contracts\LoginViewResponse] is not instantiable.

Ya que, como comentamos antes, no contamos con páginas o pantallas listas como en Breeze sí no, debemos de crearlas de manera manual (o usarlas con otras tecnologías como consumir estas rutas mediante una app en Vue).

Si comentas el módulo de registrar:

config\fortify.php

// Features::registration(),

E intentas ir a la ruta:

http://larafirstepspackages.test/register

Verás que devuelve una página de 404 ya que, acabamos de deshabilitar la acción para registrar usuarios.

Si exploras el objeto:

Fortify

Veremos muchas opciones que podemos personalizar de Fortify; si revisamos el archivo de:

app\Providers\FortifyServiceProvider.php

Veremos todas las acciones de Fortify que podemos personalizar, como el tiempo de bloqueo tras logins fallidos:

RateLimiter::for('login', function (Request $request) {
   ***

Por ejemplo, podemos especificar la vista para el login:

class FortifyServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }


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

O para registrarse:

class FortifyServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }


    public function boot(): void
    {
        ***
        Fortify::registerView(function(){
            return view('auth.register');
        });
    }
}

Creemos algunas vistas muy sencillas como las siguientes:

resources\views\auth\register.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    @if ($errors->any())
        @foreach ($errors->all() as $e)
            <div>
                {{ $e }}
            </div>
        @endforeach
    @endif
    <form action="" method="post">
        @csrf
        <input type="text" name="name" placeholder="name">
        <input type="email" name="email">
        <input type="password" name="password" >
        <input type="submit" value="Send">
    </form>
</body>
</html>

resources\views\auth\login.blade.php

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    @if ($errors->any())
        @foreach ($errors->all() as $e)
            <div>
                {{ $e }}
            </div>
        @endforeach
    @endif

    <form action="" method="post">
        @csrf
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" value="Send">
    </form>
</body>

</html>

Y al ingresar a las rutas correspondientes:

http://larafirstepspackages.test/login

http://larafirstepspackages.test/register

Verás el sistema completo para el login y registrarse provisto por Fortify; estas son solamente algunas acciones que tenemos disponibles, explorar su su uso mediante los ejemplo anteriores para que se entienda de manera práctica el funcionamiento del paquete; ya queda por parte del lector explorar el resto de las funcionalidades para que puedas emplearlos en tus proyectos que requieran emplear Fortify para crear un sistema de autenticación completamente personalizado en vez de Breeze:

https://laravel.com/docs/master/fortify

Acepto recibir anuncios de interes sobre este Blog.

Laravel Fortify es un paquete para la autenticación, registro, recuperación de contraseña, verificación de correo electrónico y más, en pocas palabras, permite realizar las mismas funcionalidades que Laravel Breeze que empleamos antes, pero sin parte gráfica.

- Andrés Cruz

In english

Este material forma parte de mi curso y libro completo; puedes adquirirlos desde el apartado de libros y/o cursos Curso y Libro Laravel 12 con Tailwind Vue 3, introducción a Jetstream Livewire e Inerta desde cero - 2025.

) )