Download Laravel App
https://laravel.com/docs/12.x/installation
Connecting our Database
open .env file root directory.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_DATABASE=laravel12dev
DB_USERNAME=root
DB_PASSWORD=root
Database Migration
php artisan migrate
myapp>php artisan migrate
Migration table created successfully.
check database table
Add username, phone to user table
php artisan make:migration "add username and phone to users table"
myapp\database\migrations\_create_add_username_and_phone_to_users_table.php
//myapp\database\migrations\_create_add_username_and_phone_to_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->string('username')->unique()->after('email'); $table->string('phone',11)->unique()->after('username'); }); } /** * Reverse the migrations. */ public function down(): void { Schema::table('users', function (Blueprint $table) { $table->dropColumn(['username', 'phone']); }); } };Create rule
php artisan make:rule NotReservedUsername
myapp/app/Rules/NotReservedUsername.php
//myapp/app/Rules/NotReservedUsername.php <?php namespace App\Rules; use Closure; use Illuminate\Contracts\Validation\ValidationRule; class NotReservedUsername implements ValidationRule { /** * Run the validation rule. * * @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail */ public function validate(string $attribute, mixed $value, Closure $fail): void { if (stripos($value, 'admin') !== false) { $fail('The username can not contain admin'); } } }Update User Modes
app/models/User.php
//app/models/User.php protected $fillable = [ 'name', 'email', 'password', 'username', 'phone' ];update code register
myapp/resources/views/livewire/auth/register.blade.php
//myapp/resources/views/livewire/auth/register.blade.php <?php use App\Models\User; use App\Rules\NotReservedUsername; use Illuminate\Auth\Events\Registered; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Illuminate\Validation\Rules; use Livewire\Attributes\Layout; use Livewire\Volt\Component; new #[Layout('components.layouts.auth')] class extends Component { public string $name = ''; public string $email = ''; public string $username = ''; public string $phone = ''; public string $password = ''; public string $password_confirmation = ''; /** * Handle an incoming registration request. */ public function register(): void { $validated = $this->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:' . User::class], 'username' => ['required', 'string', 'min:8', 'max:40', 'unique:' . User::class, 'alpha_dash', 'not_regex:/^\d+$/', new NotReservedUsername()], 'phone' => ['required', 'digits:11', 'unique:' . User::class], 'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()], ]); $validated['password'] = Hash::make($validated['password']); event(new Registered(($user = User::create($validated)))); Auth::login($user); $this->redirectIntended(route('dashboard', absolute: false), navigate: true); } }; ?> <div class="flex flex-col gap-6"> <x-auth-header :title="__('Create an account')" :description="__('Enter your details below to create your account')" /> <!-- Session Status --> <x-auth-session-status class="text-center" :status="session('status')" /> <form wire:submit="register" class="flex flex-col gap-6"> <!-- Name --> <flux:input wire:model="name" :label="__('Name')" type="text" required autofocus autocomplete="name" :placeholder="__('Full name')" /> <!-- Username --> <flux:input wire:model="username" :label="__('Username')" type="text" required autofocus autocomplete="username" :placeholder="__('Username')" /> <!-- Phone --> <flux:input wire:model="phone" :label="__('Phone Number')" type="tel" required autofocus autocomplete="phone" maxlength="11" :placeholder="__('Phone')" /> <!-- Email Address --> <flux:input wire:model="email" :label="__('Email address')" type="email" required autocomplete="email" placeholder="email@example.com" /> <!-- Password --> <flux:input wire:model="password" :label="__('Password')" type="password" required autocomplete="new-password" :placeholder="__('Password')" /> <!-- Confirm Password --> <flux:input wire:model="password_confirmation" :label="__('Confirm password')" type="password" required autocomplete="new-password" :placeholder="__('Confirm password')" /> <div class="flex items-center justify-end"> <flux:button type="submit" variant="primary" class="w-full"> {{ __('Create account') }} </flux:button> </div> </form> <div class="space-x-1 rtl:space-x-reverse text-center text-sm text-zinc-600 dark:text-zinc-400"> {{ __('Already have an account?') }} <flux:link :href="route('login')" wire:navigate>{{ __('Log in') }}</flux:link> </div> </div>update code login
myapp/resources/views/livewire/auth/login.blade.php
//myapp/resources/views/livewire/auth/login.blade.php <?php use Illuminate\Auth\Events\Lockout; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\RateLimiter; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Session; use Illuminate\Support\Str; use Illuminate\Validation\ValidationException; use Livewire\Attributes\Layout; use Livewire\Attributes\Validate; use Livewire\Volt\Component; new #[Layout('components.layouts.auth')] class extends Component { //#[Validate('required|string|email')] //public string $email = ''; #[Validate('required|string')] public string $authIdentifier = ''; #[Validate('required|string')] public string $password = ''; public bool $remember = false; /** * Handle an incoming authentication request. */ public function login(): void { $this->validate(); $this->ensureIsNotRateLimited(); //login option $login_option = "username"; if (filter_var($this->authIdentifier, FILTER_VALIDATE_EMAIL)) { $login_option = "email"; } elseif (preg_match('/^\d{11}$/', $this->authIdentifier)) { $login_option = "phone"; } if (! Auth::attempt([$login_option => $this->authIdentifier, 'password' => $this->password], $this->remember)) { RateLimiter::hit($this->throttleKey()); throw ValidationException::withMessages([ 'authIdentifier' => __('auth.failed'), ]); } RateLimiter::clear($this->throttleKey()); Session::regenerate(); $this->redirectIntended(default: route('dashboard', absolute: false), navigate: true); } /** * Ensure the authentication request is not rate limited. */ protected function ensureIsNotRateLimited(): void { if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { return; } event(new Lockout(request())); $seconds = RateLimiter::availableIn($this->throttleKey()); throw ValidationException::withMessages([ 'authIdentifier' => __('auth.throttle', [ 'seconds' => $seconds, 'minutes' => ceil($seconds / 60), ]), ]); } /** * Get the authentication rate limiting throttle key. */ protected function throttleKey(): string { return Str::transliterate(Str::lower($this->authIdentifier) . '|' . request()->ip()); } }; ?> <div class="flex flex-col gap-6"> <x-auth-header :title="__('Log in to your account')" :description="__('Enter your email and password below to log in')" /> <!-- Session Status --> <x-auth-session-status class="text-center" :status="session('status')" /> <form wire:submit="login" class="flex flex-col gap-6"> <!-- Email Address --> <flux:input wire:model="authIdentifier" :label="__('Email, Username or Phone')" type="text" required autofocus placeholder="Email, Username or Phone" /> <!-- Password --> <div class="relative"> <flux:input wire:model="password" :label="__('Password')" type="password" required autocomplete="current-password" :placeholder="__('Password')" /> @if (Route::has('password.request')) <flux:link class="absolute end-0 top-0 text-sm" :href="route('password.request')" wire:navigate> {{ __('Forgot your password?') }} </flux:link> @endif </div> <!-- Remember Me --> <flux:checkbox wire:model="remember" :label="__('Remember me')" /> <div class="flex items-center justify-end"> <flux:button variant="primary" type="submit" class="w-full">{{ __('Log in') }}</flux:button> </div> </form> @if (Route::has('register')) <div class="space-x-1 rtl:space-x-reverse text-center text-sm text-zinc-600 dark:text-zinc-400"> {{ __('Don\'t have an account?') }} <flux:link :href="route('register')" wire:navigate>{{ __('Sign up') }}</flux:link> </div> @endif </div>run php artisan serve and npm run dev
Run myapp>composer run dev