Laravel Fortify, what it is, when to use and first steps

Laravel Fortify is a package for authentication, registration, password recovery, email verification and more, in short, it allows you to perform the same functionalities as Laravel Breeze that we used before, but the difference is that it is not as intrusive, when We install Laravel Breeze, it installs Tailwind.css and generates various components, controllers, views and associated routes; in the case of Laravel Fortify this is not the case and it provides us with the same features but without the need for the graphical interface, therefore, it is particularly useful if you want to develop a more personalized authentication backend than the one offered by Breeze; It is important to note that if you are using Laravel Breeze or a similar solution, it is not necessary to use Laravel Fortify.

 

Another possible comparison that you may be making is with Sanctum, Laravel Fortify and Laravel Sanctum are not mutually exclusive or competing packages, otherwise they can be used in the same project if required, Laravel Sanctum only takes care of managing tokens API and authenticate existing users using cookies or session tokens. Sanctum does not provide any route that handles user registration, password reset, etc, in a nutshell Sanctum is focused on authenticating a Rest API and Laravel Fortify for a traditional web application.

Installation and configuration

Para instalar Laravel Fortify empleamos el siguiente comando:

$ composer require laravel/fortify

The next step is to run the installation command:

$ php artisan fortify:install

This command will generate the migrations, configuration files, providers, among others.

We execute the migrations:

$ php artisan migrate

And with this, we can now use Laravel Fortify.

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

config\fortify.php

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

Features

They allow you to disable/enable the registration option, reset the password and email verification respectively. If you do not want to use one or more of these options, you simply have to comment on it, for example, if you want to deactivate email verification:

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

To exemplify its use, if we do:

$ php artisan r:l

We will see all the routes generated by 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

If we enter the login page, we will see an error like the following:

http://larafirstepspackages.test/login

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

Since, as we mentioned before, we do not have ready pages or screens like in Breeze, we must create them manually (or use them with other technologies such as consuming these routes through an app in Vue).

If you comment on the register module:

confg\fortify.php

// Features::registration(),

And you try to go to the route:

http://larafirstepspackages.test/register

You will see that it returns a 404 page since we have just disabled the action to register users.

If you explore the object:

Fortify

We will see many options that we can customize for Fortify; if we check the file:

app\Providers\FortifyServiceProvider.php

We will see all the Fortify actions that we can customize, such as the blocking time after failed logins:

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

For example, we can specify the view for the login:

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


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

Or to register:

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


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

Let's create some very simple views like the following:

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>

And when entering the corresponding routes:

http://larafirstepspackages.test/login

http://larafirstepspackages.test/register

You will see the complete system for login and registration provided by Fortify; these are just some actions that we have available, explore their use using the previous examples so that you can practically understand how the package works; It is up to the reader to explore the rest of the functionalities so that you can use them in your projects that require using Fortify to create a completely personalized authentication system instead of Breeze:

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

- Andrés Cruz

En español

This material is part of my complete course and book; You can purchase them from the books and/or courses section, Curso y libro Laravel 11 con Tailwind Vue 3, introducción a Jetstream Livewire e Inerta desde cero - 2024.

Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.