Customize Laravel Auth (Laravel Breeze Registration and Login)

kingsconsult

Kingsconsult

Posted on December 10, 2020

Customize Laravel Auth (Laravel Breeze Registration and Login)

Hello Artisans, after making a post on Basic Laravel Login and Registration using Laravel Breeze, I got a lot of private messages on how to customize the Registration and Login where a developer can be able to add more fields because the default Laravel User Registration fields are just limited to Name, Email and Password right from the time of the Legacy UI till the time of writing this report. But there are instances of where a developer might want to collect not just the name, but First Name, Last Name, Username, Password or even making the Email not mandatory for users who don't have email, so I decide to write this little piece.
For this article, I am going to use the app from this article Basic Laravel Login and Registration using Laravel Breeze

Click on my profile to follow me to get more updates.

Step 1: Edit the RegisteredUserController

Go to app/Http/Controllers/Auth/RegisteredUserController.php and customize the store method to this



    public function store(Request $request)
    {
        $request->validate([
            'firstname' => 'required|string|max:255',
            'lastname' => 'required|string|max:255',
            'password' => 'required|string|confirmed|min:8',
            'username' => 'required|string|max:255',
        ]);

        Auth::login($user = User::create([
            'firstname' => $request->firstname,
            'lastname' => $request->lastname,
            'username' => $request->username,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]));

        event(new Registered($user));

        return redirect(RouteServiceProvider::HOME);
    }


Enter fullscreen mode Exit fullscreen mode

In the validate( ) method, I removed email, and added firstname, lastname and username. Also in the User::create, I added the new fields.

Step 2: Create another migration file to add the new fields to the User and login_history table

This migration field will add the new fields to our existing users table, so run the command below

php artisan make:migration add_more_fields_to_users_table --table=users

Do the same for the login_history table.
The --table=users flag will specify the type of schema facade to use.
A migrations file will be created, go to database/migrations/ Migration files

Step 3: Add the new fields and modify the name field

We are going to modify the existing name field with firstname and also add other fields, but to modify an existing fields, we need a package doctrine/dbal, The Doctrine DBAL library is used to determine the current state of the column and to create the SQL queries needed to make the requested changes to your column. Laravel docs

composer require doctrine/dbal

After this, update the composer, by running the command below

composer update

php artisan command
Then add the following fields to the up( ) method of the migration file created above



    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->renameColumn('name', 'firstname');
            $table->string('lastname');
            $table->string('username');
            $table->string('email')->nullable()->change();
        });
    }


Enter fullscreen mode Exit fullscreen mode

You will notice how we are going to rename our name field to firstname and added lastname and username, also we modify file email from mandatory to nullable().

Don't forget to do the same for the login_history.
Finally, run the migration command, but

php artisan migrate

php artisan migrate
Database
Database

Step 4: Modify the Users Model

We need to add the fields to be fill in users model, go to app/Models/User.php and edit the protected $fillable to add the new fields



    protected $fillable = [
        'firstname',
        'email',
        'password',
        'username',
        'lastname'
    ];


Enter fullscreen mode Exit fullscreen mode

Step 5: Modify the Registration view

Go to resources/views/auth/register.blade.php and modify to this



<x-guest-layout>
    <x-auth-card>
        <x-slot name="logo">
            <a href="/">
                <x-application-logo class="w-20 h-20 fill-current text-gray-500" />
            </a>
        </x-slot>

        <!-- Validation Errors -->
        <x-auth-validation-errors class="mb-4" :errors="$errors" />

        <form method="POST" action="{{ route('register') }}">
            @csrf

            <!-- Name -->
            <div>
                <x-label for="firstname" :value="__('First Name')" />

                <x-input id="firstname" class="block mt-1 w-full" type="text" name="firstname" required autofocus />
            </div>
            <!-- Name -->
            <div>
                <x-label for="lastname" :value="__('Last Name')" />

                <x-input id="lastname" class="block mt-1 w-full" type="text" name="lastname" required />
            </div>
            <!-- Name -->
            <div>
                <x-label for="username" :value="__('username')" />

                <x-input id="username" class="block mt-1 w-full" type="text" name="username" required />
            </div>

            <!-- Email Address -->
            <div class="mt-4">
                <x-label for="email" :value="__('Email')" />

                <x-input id="email" class="block mt-1 w-full" type="email" name="email"  />
            </div>

            <!-- Password -->
            <div class="mt-4">
                <x-label for="password" :value="__('Password')" />

                <x-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" />
            </div>

            <!-- Confirm Password -->
            <div class="mt-4">
                <x-label for="password_confirmation" :value="__('Confirm Password')" />

                <x-input id="password_confirmation" class="block mt-1 w-full" type="password" name="password_confirmation" required />
            </div>

            <div class="flex items-center justify-end mt-4">
                <x-button>
                    {{ __('Register') }}
                </x-button>
            </div>
        </form>
    </x-auth-card>
</x-guest-layout>


Enter fullscreen mode Exit fullscreen mode

Start our application with

php artisan serve

Click on Register, we are going to have this
register

Step 6: Modify the Login view

Go to resources/views/auth/login.blade.php and modify to this



<x-guest-layout>
    <x-auth-card>
        <x-slot name="logo">
            <a href="/">
                <x-application-logo class="w-20 h-20 fill-current text-gray-500" />
            </a>
        </x-slot>

        <!-- Session Status -->
        <x-auth-session-status class="mb-4" :status="session('status')" />

        <!-- Validation Errors -->
        <x-auth-validation-errors class="mb-4" :errors="$errors" />

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

            <!-- Email Address -->
            <div>
                <x-label for="username" :value="__('Username')" />

                <x-input id="username" class="block mt-1 w-full" type="text" name="username" required autofocus />
            </div>

            <!-- Password -->
            <div class="mt-4">
                <x-label for="password" :value="__('Password')" />

                <x-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" />
            </div>

            <!-- Remember Me -->
            <div class="block mt-4">
                <label for="remember_me" class="flex items-center">
                    <input id="remember_me" type="checkbox" class="form-checkbox" name="remember">
                    <span class="ml-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
                </label>
            </div>

            <div class="flex items-center justify-end mt-4">
                @if (Route::has('password.request'))
                <a class="underline text-sm text-gray-600 hover:text-gray-900" href="{{ route('password.request') }}">
                    {{ __('Forgot your password?') }}
                </a>
                @endif

                <x-button class="ml-3">
                    {{ __('Login') }}
                </x-button>
            </div>
        </form>
    </x-auth-card>
</x-guest-layout>


Enter fullscreen mode Exit fullscreen mode

This will change the login field from email to username

Step 7: Modify the Login Request Class

This is the class that replaces the LoginController class in the previous Laravel Authentication. Go to app/Requests/Auth/LoginRequest.php and change all the email string to username string, and also make sure the validating rules, you remove the email rule and replace it with username rule



<?php

namespace App\Http\Requests\Auth;

use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use App\Events\LoginHistory;



class LoginRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'username' => 'required|string',
            'password' => 'required|string',
        ];
    }

    /**
     * Attempt to authenticate the request's credentials.
     *
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function authenticate()
    {
        $this->ensureIsNotRateLimited();

        if (! Auth::attempt($this->only('username', 'password'), $this->filled('remember'))) {
            RateLimiter::hit($this->throttleKey());

            throw ValidationException::withMessages([
                'username' => __('auth.failed'),
            ]);
        }

        $user = Auth::user();

        event(new LoginHistory($user));

        RateLimiter::clear($this->throttleKey());
    }

    /**
     * Ensure the login request is not rate limited.
     *
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function ensureIsNotRateLimited()
    {
        if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
            return;
        }

        event(new Lockout($this));

        $seconds = RateLimiter::availableIn($this->throttleKey());

        throw ValidationException::withMessages([
            'username' => trans('auth.throttle', [
                'seconds' => $seconds,
                'minutes' => ceil($seconds / 60),
            ]),
        ]);
    }

    /**
     * Get the rate limiting throttle key for the request.
     *
     * @return string
     */
    public function throttleKey()
    {
        return Str::lower($this->input('username')).'|'.$this->ip();
    }
}


Enter fullscreen mode Exit fullscreen mode

Logout from the app and click on login
login page
dashboard after login

We can now login with username and password instead of email address. That is all
Follow me for more of my articles, you can leave comments, suggestions, and reactions.
I am open to any vacancy as a PHP backend engineer, my strength is in the Laravel framework

click the link to view my profile and follow me

💖 💪 🙅 🚩
kingsconsult
Kingsconsult

Posted on December 10, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related