Customize Laravel Jetstream Registration and Login Example
In this post, i will tell you how to customize laravel jetstream register and login page. we will add username field in users table and add it to registeration page. Then we will login with username and password fields with existing laravel jetstream setup code.
After installing Laravel Jetstream, we'll add first_name, last_name, and username columns to the registration page. We'll also enable users to log in using either their email or username. Let's go through the steps:
Add Fields to users Table
First, you need to add first_name, last_name and username fields into users table and add to User model as well.
let's run the following to create migration.
php artisan make:migration add_fields_column_in_users_table
You need to update the following code on that file:
database/migrations/2024_10_15_115318_add_fields_column_in_users_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn("name");
$table->string("first_name");
$table->string("last_name");
$table->string("username")->unique();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
//
});
}
};
Now, run the created migration:
php artisan migrate
Next, let's add username field in fillable variable in the User model file.
app/Models/User.php
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
/** @use HasFactory */
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'first_name',
'last_name',
'email',
'password',
'username'
];
...
Update Registration Page:
Now, we will add username field in the register.blade.php file. so, let's update like the following way:
resources/views/auth/register.blade.php
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />
</x-slot>
<x-validation-errors class="mb-4" />
<form method="POST" action="{{ route('register') }}">
@csrf
<div>
<x-label for="first_name" value="{{ __('First Name') }}" />
<x-input id="first_name" class="block mt-1 w-full" type="text" name="first_name" :value="old('first_name')" required autofocus autocomplete="first_name" />
</div>
<div class="mt-4">
<x-label for="last_name" value="{{ __('Last Name') }}" />
<x-input id="last_name" class="block mt-1 w-full" type="text" name="last_name" :value="old('last_name')" required autocomplete="username" />
</div>
<div class="mt-4">
<x-label for="username" value="{{ __('Username') }}" />
<x-input id="username" class="block mt-1 w-full" type="text" name="username" :value="old('username')" required autocomplete="username" />
</div>
<div class="mt-4">
<x-label for="email" value="{{ __('Email') }}" />
<x-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autocomplete="username" />
</div>
<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>
<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 autocomplete="new-password" />
</div>
@if (Laravel\Jetstream\Jetstream::hasTermsAndPrivacyPolicyFeature())
<div class="mt-4">
<x-label for="terms">
<div class="flex items-center">
<x-checkbox name="terms" id="terms" required />
<div class="ms-2">
{!! __('I agree to the :terms_of_service and :privacy_policy', [
'terms_of_service' => '<a target="_blank" href="'.route('terms.show').'" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">'.__('Terms of Service').'</a>',
'privacy_policy' => '<a target="_blank" href="'.route('policy.show').'" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">'.__('Privacy Policy').'</a>',
]) !!}
</div>
</div>
</x-label>
</div>
@endif
<div class="flex items-center justify-end mt-4">
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="{{ route('login') }}">
{{ __('Already registered?') }}
</a>
<x-button class="ms-4">
{{ __('Register') }}
</x-button>
</div>
</form>
</x-authentication-card>
</x-guest-layout>
Now, we will update the CreateNewUser.php with the following code:
app/Actions/Fortify/CreateNewUser.php
<?php
namespace App\Actions\Fortify;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Laravel\Jetstream\Jetstream;
class CreateNewUser implements CreatesNewUsers
{
use PasswordValidationRules;
/**
* Validate and create a newly registered user.
*
* @param array $input
*/
public function create(array $input): User
{
Validator::make($input, [
'first_name' => ['required', 'string', 'max:255'],
'last_name' => ['required', 'string', 'max:255'],
'username' => ['required', 'string', 'max:255', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['accepted', 'required'] : '',
])->validate();
return User::create([
'first_name' => $input['first_name'],
'last_name' => $input['last_name'],
'username' => $input['username'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
}
}
Update Login Page:
Now, we will add username field in the login.blade.php file. so, let's update like the following way:
resources/views/auth/login.blade.php
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />
</x-slot>
<x-validation-errors class="mb-4" />
@session('status')
<div class="mb-4 font-medium text-sm text-green-600 dark:text-green-400">
{{ $value }}
</div>
@endsession
<form method="POST" action="{{ route('login') }}">
@csrf
<div>
<x-label for="login" value="{{ __('Email/Username') }}" />
<x-input id="login" class="block mt-1 w-full" type="text" name="login" :value="old('login')" required autofocus autocomplete="username" />
</div>
<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>
<div class="block mt-4">
<label for="remember_me" class="flex items-center">
<x-checkbox id="remember_me" name="remember" />
<span class="ms-2 text-sm text-gray-600 dark:text-gray-400">{{ __('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 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="{{ route('password.request') }}">
{{ __('Forgot your password?') }}
</a>
@endif
<x-button class="ms-4">
{{ __('Log in') }}
</x-button>
</div>
</form>
</x-authentication-card>
</x-guest-layout>
Now, we will update the FortifyServiceProvider.php with the following code:
app/Providers/FortifyServiceProvider.php
<?php
namespace App\Providers;
use App\Actions\Fortify\CreateNewUser;
use App\Actions\Fortify\ResetUserPassword;
use App\Actions\Fortify\UpdateUserPassword;
use App\Actions\Fortify\UpdateUserProfileInformation;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Laravel\Fortify\Fortify;
use App\Models\User;
use Hash;
class FortifyServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::createUsersUsing(CreateNewUser::class);
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
Fortify::authenticateUsing(function(Request $request){
$user = User::where("email", $request->login)
->orWhere("username", $request->login)
->first();
if ($user & Hash::check($request->password, $user->password)) {
return $user;
}
});
RateLimiter::for('login', function (Request $request) {
$throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip());
return Limit::perMinute(5)->by($throttleKey);
});
RateLimiter::for('two-factor', function (Request $request) {
return Limit::perMinute(5)->by($request->session()->get('login.id'));
});
}
}
Now, you can run the application and you will see the following output:
i hope it can help you...
Hardik Savani
I'm a full-stack developer, entrepreneur and owner of ItSolutionstuff.com. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Laravel, Angular, Vue, Node, Javascript, JQuery, Codeigniter and Bootstrap from the early stage. I believe in Hardworking and Consistency.
We are Recommending you
- Laravel Breeze Auth: Login With Email Or Username Example
- Laravel UI Auth: Login With Email Or Username Example
- How to Implement Email Verification in Laravel?
- How to Customize Laravel Breeze Authentication?
- Laravel Breeze Change Redirect After Login/Register
- Laravel 11 Razorpay Payment Gateway Integration Example
- Laravel 11 Google Recaptcha V3 Validation Tutorial
- How to Create Event Calendar in Laravel 11?
- Laravel 11 Drag and Drop File Upload with Dropzone JS
- Laravel 11 ChartJS Chart Example Tutorial
- Laravel 11 Resize Image Before Upload Example
- Laravel 11 Send Email using Queue Example
- Laravel 11 Ajax Form Validation Example Tutorial