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 Modesapp/models/User.php
//app/models/User.php
protected $fillable = [
'name',
'email',
'password',
'username',
'phone'
];
update code registermyapp/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 loginmyapp/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
