DEV Community

Kingsconsult
Kingsconsult

Posted on

Customize Laravel Jetstream (Registration and Login)

Hello, welcome back to my series, previously, I wrote on how to Customize Laravel Auth (Laravel Breeze Registration and Login), this is for those that use Laravel breeze for Authentification, but some of my readers who used Laravel Jetstream are still finding it difficult to customize the Registration and Login process in order to suit their needs.
For those that did not read the previous article, what we are trying to achieve is to customize the Registration and Login whereby a developer can choose to use username and password for login different from the default email and password, this is because some of the users of your application might not be having email address, so the person might use username for the registration and be using it for login.
without further ado, let's dive into the stuff of the day, if you read Customize Laravel Auth (Laravel Breeze Registration and Login), most of the steps are similar.

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

Step 1: Edit the CreateNewUser.php

If you scaffold your authentication using Laravel Jetstream and installed livewire or inertia, you will have an Action folder in your App directory, and also a Fortify directory inside the Action with some files.
Go to app/Actions/Fortify/CreateNewUser.php customize the create method to this

  public function create(array $input)
    {
        Validator::make($input, [
            'firstname' => ['required', 'string', 'max:255'],
            'lastname' => ['required', 'string', 'max:255'],
            'username' => ['required', 'string', 'max:255'],
            'password' => $this->passwordRules(),
        ])->validate();

        return User::create([
            'firstname' => $input['firstname'],
            'lastname' => $input['lastname'],
            'username' => $input['username'],
            'email' => $input['email'],
            'password' => Hash::make($input['password']),
        ]);
    }
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 table

php artisan make:migration add_more_fields_to_users_table --table=users

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')->unique();
            $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, we made the username to be unique() and also modify email from mandatory to nullable().

Finally, run the migration command

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-jet-authentication-card>
        <x-slot name="logo">
            <x-jet-authentication-card-logo />
        </x-slot>

        <x-jet-validation-errors class="mb-4" />

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

            <div>
                <x-jet-label value="{{ __('First Name') }}" />
                <x-jet-input class="block mt-1 w-full" type="text" name="firstname" :value="old('firstname')" required autofocus autocomplete="firstname" />
            </div>

            <div>
                <x-jet-label value="{{ __('Last Name') }}" />
                <x-jet-input class="block mt-1 w-full" type="text" name="lastname" :value="old('lastname')" required autocomplete="lastname" />
            </div>

            <div>
                <x-jet-label value="{{ __('Username') }}" />
                <x-jet-input class="block mt-1 w-full" type="text" name="username" :value="old('username')" autocomplete="username" />
            </div>

            <div class="mt-4">
                <x-jet-label value="{{ __('Email') }}" />
                <x-jet-input class="block mt-1 w-full" type="email" name="email" :value="old('email')"  />
            </div>

            <div class="mt-4">
                <x-jet-label value="{{ __('Password') }}" />
                <x-jet-input class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" />
            </div>

            <div class="mt-4">
                <x-jet-label value="{{ __('Confirm Password') }}" />
                <x-jet-input class="block mt-1 w-full" type="password" name="password_confirmation" required autocomplete="new-password" />
            </div>

            <div class="flex items-center justify-end mt-4">
                <a class="underline text-sm text-gray-600 hover:text-gray-900" href="{{ route('login') }}">
                    {{ __('Already registered?') }}
                </a>

                <x-jet-button class="ml-4">
                    {{ __('Register') }}
                </x-jet-button>
            </div>
        </form>
    </x-jet-authentication-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-jet-authentication-card>
        <x-slot name="logo">
            <x-jet-authentication-card-logo />
        </x-slot>

        <x-jet-validation-errors class="mb-4" />

        @if (session('status'))
        <div class="mb-4 font-medium text-sm text-green-600">
            {{ session('status') }}
        </div>
        @endif

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

            <div>
                <x-jet-label value="{{ __('Username') }}" />
                <x-jet-input class="block mt-1 w-full" type="text" name="username" :value="old('username')" required autofocus />
            </div>

            <div class="mt-4">
                <x-jet-label value="{{ __('Password') }}" />
                <x-jet-input class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" />
            </div>

            <div class="block mt-4">
                <label class="flex items-center">
                    <input 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-jet-button class="ml-4">
                    {{ __('Login') }}
                </x-jet-button>
            </div> 
        </form>
    </x-jet-authentication-card>
</x-guest-layout>
Enter fullscreen mode Exit fullscreen mode

We removed email field and replace it with username field

Step 7: Modify the Fortify configuration file

We are going to specify what we are going to be using for the login, so go to config/fortify.php, you will see an array, find the username key and change it to username from email,

  'username' => 'username',
Enter fullscreen mode Exit fullscreen mode

Then clear your config and cache

php artisan config:cache

Run your app in case it is down

php artisan serve

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

Top comments (7)

Collapse
 
safventure11000 profile image
Josafe Balili • Edited

I slightly got overwhelmed with the changes of laravel 8 esp with laravel jetstream. That’s why I prefer the laravel breeze which is simpler. The simpler the better. But I’m glad that someone wrote about jetstream. Given the overall complexity that jetstream add to the laravel project, I think it’s worth to try and explore.

Collapse
 
nicotravassos profile image
Nico Travassos

Where ranaming $table->renameColumn('name', 'firstname'); a column can I also make it nullable in the same line?

Collapse
 
thejoshuabowers profile image
Joshua Bowers

Bro... this is an amazing and clear tutorial. Best I've seen in a long time. Thanks a lot!

Collapse
 
yaminshakil profile image
yamin

sir , can you make a tutorial for multiplle authentication in laravel jetstream

Collapse
 
cocobyon profile image
cocobyon • Edited

bro could you please help me how to add nav menu and use your layout ?

and please help me how to add some logic to call specific model in controller dashboard?

thank you sir

Collapse
 
aris profile image
Aris Ripandi

Thanks before, this is exactly what i need. But, I got error, where is LoginHistory class?

Collapse
 
djcorea profile image
djcorea

Is it possible to use any of them without migrations?
I've ready have my database.