Adding two-factor auth to Laravel 8 bootstrap livewire fortify project

In part one of this article, we created our authentication setup using fortify, laravel and bootstrap.

Part 1

In part two of this article, we covered updating your profile information and how to change your password from your profile page using liv…


This content originally appeared on DEV Community and was authored by Jasmine Tracey

In part one of this article, we created our authentication setup using fortify, laravel and bootstrap.

Part 1

In part two of this article, we covered updating your profile information and how to change your password from your profile page using livewire

Part 2

In this tutorial, We will cover:

  • adding two-factor auth to your project

Clone part one of our project

git clone --branch starter2 git@github.com:jasminetracey/lara8auth.git
cd lara8auth

Open your cloned project in IDE of choice I will be using Visual Studio Code

Install Alpine.js

We will be installing alpine.js to do some showing and hiding in the two factor form

npm install --save alpinejs

Import package in the resources/js/app.js file

...

import Alpine from 'alpinejs';

window.Alpine = Alpine;

Alpine.start();

...

Update Fortify Provider

To begin we will be updating our fortify provider to enable the 2factor page when the user logs in.

public function boot()
{
    ...

    Fortify::twoFactorChallengeView(function () {
        return view('auth.two-factor-challenge');
    });

    ...
}

Create two-factor auth view

touch resources/views/auth/two-factor-challenge.blade.php
@extends('layouts.app') 

@section('content')
<div class="container" x-data="{ recovery: false }">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <div class="alert alert-info" role="alert" x-show="! recovery">
                        {{ __('Please confirm access to your account by entering the authentication
                        code provided by your authenticator application.') }}
                    </div>

                    <div class="alert alert-info" role="alert" x-show="recovery">
                        {{ __('Please confirm access to your account by entering one of your
                        emergency recovery codes.') }}
                    </div>

                    <form method="POST" action="{{ route('two-factor.login') }}">
                        @csrf

                        <div class="form-group row" x-show="! recovery">
                            <label for="code" class="col-md-4 col-form-label text-md-right"
                                >{{ __('Code') }}</label
                            >

                            <div class="col-md-6">
                                <input
                                    id="code"
                                    type="text"
                                    class="form-control @error('code') is-invalid @enderror"
                                    name="code"
                                    value="{{ old('code') }}"
                                    autocomplete="one-time-code"
                                />

                                @error('code')
                                <span class="invalid-feedback" role="alert">
                                    <strong>{{ $message }}</strong>
                                </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row" x-show="recovery">
                            <label for="recovery_code" class="col-md-4 col-form-label text-md-right"
                                >{{ __('Recovery Code') }}</label
                            >

                            <div class="col-md-6">
                                <input
                                    id="recovery_code"
                                    type="text"
                                    class="form-control @error('recovery_code') is-invalid @enderror"
                                    name="recovery_code"
                                    value="{{ old('recovery_code') }}"
                                    autocomplete="one-time-code"
                                />

                                @error('recovery_code')
                                <span class="invalid-feedback" role="alert">
                                    <strong>{{ $message }}</strong>
                                </span>
                                @enderror
                            </div>
                        </div>

                        <div class="flex items-center justify-end mt-4"></div>

                        <div class="mb-0 form-group row">
                            <div class="col-md-3 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>
                            </div>

                            <div class="col-md-5">
                                <button
                                    type="button"
                                    class="btn btn-secondary"
                                    x-show="! recovery"
                                    x-on:click="
                                                                    recovery = true;
                                                                    $nextTick(() => { $refs.recovery_code.focus() })
                                                                "
                                >
                                    {{ __('Use a recovery code') }}
                                </button>

                                <button
                                    type="button"
                                    class="btn btn-secondary"
                                    x-show="recovery"
                                    x-on:click="
                                                                    recovery = false;
                                                                    $nextTick(() => { $refs.code.focus() })
                                                                "
                                >
                                    {{ __('Use an authentication code') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Update User Model

We also need to tell our user model that we will be enabling 2factor authentication so we need to add a trait TwoFactorAuthenticatable

...
use Laravel\Fortify\TwoFactorAuthenticatable;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasFactory, Notifiable, TwoFactorAuthenticatable;
...

Create livewire enable two-factor form

This form will be used to manage 2factor authentication. This includes enabling, disabling, and regenerating recovrey codes.

From your terminal run the following command php artisan livewire:make two-factor-form This will create our livewire component.

In your resources/views/livewire/profile-form.blade.php add the following code to create our form fields.

<section class="my-5">
    @if (session('status') == 'two-factor-authentication-enabled')
    <div class="mb-4 text-sm font-medium text-green-600">
        Two factor authentication has been enabled.
    </div>
    @endif

    <div class="card">
        <div class="card-body">
            <h5 class="card-title">Two-Factor Authentication</h5>

            @if (!empty($this->user->two_factor_secret)) 

                @if ($showQrCode)
                    <p>
                        Two factor authentication is now enabled. Scan the following QR code using your
                        phone's authenticator application.
                    </p>

                    <div>{!! $this->user->twoFactorQrCodeSvg() !!}</div>
                @endif 

                @if ($showRecoveryCodes)
                    <div class="mt-4">
                        <p>
                            Store these recovery codes in a secure password manager. They can be used to
                            recover access to your account if your two factor authentication device is lost.
                        </p>

                        <div>
                            @foreach (json_decode(decrypt($this->user->two_factor_recovery_codes), true) as
                            $code)
                                <div>{{ $code }}</div>
                            @endforeach
                        </div>
                    </div>
                @endif

                <div class="mt-4">
                    @if ($showRecoveryCodes)
                        <button wire:click="regenerateRecoveryCodes" class="btn btn-secondary">
                            Regenerate Recovery Codes
                        </button>
                    @else
                        <button wire:click="showRecoveryCodes" class="btn btn-secondary">
                            Show Recovery Codes
                        </button>
                    @endif

                    <button wire:click="disableTwoFactorAuth" class="btn btn-primary">
                        Disable Two-Factor Authentication
                    </button>
                </div>

            @else
                <div>
                    <p>You have not enabled two factor authentication.</p>

                    <button wire:click="enableTwoFactorAuth" class="btn btn-primary">
                        Enable Two-Factor Authentication
                    </button>
                </div>
            @endif
        </div>
    </div>
</section>

After adding our view we need to add the code in the livewire component file app\Http\Livewire\TwoFactorForm.php to interact with fields.

We will first add two fields to the component to hide and show QRCode and the RecoveryCode. And the function to toggle showing the recovery codes.

public $showQrCode = false;
public $showRecoveryCodes = false;

public function showRecoveryCodes()
{
    $this->showRecoveryCodes = true;
}

Next we will include a user property to the component because we will be interacting with a couple fields on the authenticated user.

public function getUserProperty()
{
    return Auth::user();
}

The first function we will be adding is the enableTwoFactorAuth function. This is the one that gets the ball rolling and allowing the user to setup two-factor authentication. We will be using the EnableTwoFactorAuthentication action that comes with fortify.

public function enableTwoFactorAuth(EnableTwoFactorAuthentication $enable)
{
    $enable(Auth::user());

    $this->showQrCode = true;
    $this->showRecoveryCodes = true;
}

Remember to import the EnableTwoFactorAuthentication action

The next function will be the disableTwoFactorAuth function. If for some reason the user no longer wishes to have to factor authentication on their account we will provide the option to disable it. Again we will be using a fortify action DisableTwoFactorAuthentication.

public function disableTwoFactorAuth(DisableTwoFactorAuthentication $disable)
{
    $disable(Auth::user());
}

Remember to import the DisableTwoFactorAuthentication action

Finally we will be adding a function to regenerate recovery codes. These recovery codes allow the user to authenticate if they lose access to their mobile device.

public function regenerateRecoveryCodes(GenerateNewRecoveryCodes $generate)
{
    $generate(Auth::user());

    $this->showRecoveryCodes = true;
}

Remember to import the GenerateNewRecoveryCodes action

Finally, we will add our component to the resources/views/profile.blade.php page so that we can see the form when we visit the profile page.

@extends('layouts.app') 

@section('content')
    <div class="container">
        <livewire:profile-form />

        <livewire:password-change-form />

        <livewire:two-factor-form />
    </div>
@endsection

Now when you go to /profile you should have the working 2factor form.

Conclusion

To find out more about laravel fortify features you can go the the github respository Fortify and for livewire documentation you can go to livewire

Thanks for reading please comment below and share if you found this article helpful.

GitHub logo jasminetracey / lara8auth

This is a simple auth starter setup for laravel 8 projects using bootstrap and laravel fortify

BOOTSTRAP 4 LARAVEL FORTIFY AUTHENTICATION

This is a simple auth starter setup for laravel 8 projects

Features

  • User Login
  • User Registration
  • Email Verification
  • Forget Password
  • Reset Password
  • Change Password
  • Update User Profile
  • TwoFactor Authentication
  • Browser Session Management


This content originally appeared on DEV Community and was authored by Jasmine Tracey


Print Share Comment Cite Upload Translate Updates
APA

Jasmine Tracey | Sciencx (2021-09-27T22:19:08+00:00) Adding two-factor auth to Laravel 8 bootstrap livewire fortify project. Retrieved from https://www.scien.cx/2021/09/27/adding-two-factor-auth-to-laravel-8-bootstrap-livewire-fortify-project/

MLA
" » Adding two-factor auth to Laravel 8 bootstrap livewire fortify project." Jasmine Tracey | Sciencx - Monday September 27, 2021, https://www.scien.cx/2021/09/27/adding-two-factor-auth-to-laravel-8-bootstrap-livewire-fortify-project/
HARVARD
Jasmine Tracey | Sciencx Monday September 27, 2021 » Adding two-factor auth to Laravel 8 bootstrap livewire fortify project., viewed ,<https://www.scien.cx/2021/09/27/adding-two-factor-auth-to-laravel-8-bootstrap-livewire-fortify-project/>
VANCOUVER
Jasmine Tracey | Sciencx - » Adding two-factor auth to Laravel 8 bootstrap livewire fortify project. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/27/adding-two-factor-auth-to-laravel-8-bootstrap-livewire-fortify-project/
CHICAGO
" » Adding two-factor auth to Laravel 8 bootstrap livewire fortify project." Jasmine Tracey | Sciencx - Accessed . https://www.scien.cx/2021/09/27/adding-two-factor-auth-to-laravel-8-bootstrap-livewire-fortify-project/
IEEE
" » Adding two-factor auth to Laravel 8 bootstrap livewire fortify project." Jasmine Tracey | Sciencx [Online]. Available: https://www.scien.cx/2021/09/27/adding-two-factor-auth-to-laravel-8-bootstrap-livewire-fortify-project/. [Accessed: ]
rf:citation
» Adding two-factor auth to Laravel 8 bootstrap livewire fortify project | Jasmine Tracey | Sciencx | https://www.scien.cx/2021/09/27/adding-two-factor-auth-to-laravel-8-bootstrap-livewire-fortify-project/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.