login.blade.php (3929B)
1 <?php 2 3 use App\Providers\RouteServiceProvider; 4 use Illuminate\Auth\Events\Lockout; 5 use Illuminate\Support\Facades\RateLimiter; 6 use Illuminate\Support\Str; 7 use Illuminate\Validation\ValidationException; 8 use Livewire\Attributes\Layout; 9 use Livewire\Attributes\Rule; 10 use Livewire\Volt\Component; 11 12 new #[Layout('layouts.guest')] class extends Component { 13 #[Rule(['required', 'string', 'email'])] 14 public string $email = ''; 15 16 #[Rule(['required', 'string'])] 17 public string $password = ''; 18 19 #[Rule(['boolean'])] 20 public bool $remember = false; 21 22 public function login(): void 23 { 24 $this->validate(); 25 26 $this->ensureIsNotRateLimited(); 27 28 if (!auth()->attempt($this->only(['email', 'password'], $this->remember))) { 29 RateLimiter::hit($this->throttleKey()); 30 31 throw ValidationException::withMessages([ 32 'email' => trans('auth.failed'), 33 ]); 34 } 35 36 RateLimiter::clear($this->throttleKey()); 37 38 session()->regenerate(); 39 40 $this->redirect(session('url.intended', RouteServiceProvider::HOME), navigate: true); 41 } 42 43 protected function ensureIsNotRateLimited(): void 44 { 45 if (!RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { 46 return; 47 } 48 49 event(new Lockout(request())); 50 51 $seconds = RateLimiter::availableIn($this->throttleKey()); 52 53 throw ValidationException::withMessages([ 54 'email' => trans('auth.throttle', [ 55 'seconds' => $seconds, 56 'minutes' => ceil($seconds / 60), 57 ]), 58 ]); 59 } 60 61 protected function throttleKey(): string 62 { 63 return Str::transliterate(Str::lower($this->email) . '|' . request()->ip()); 64 } 65 }; ?> 66 67 <div> 68 <!-- Session Status --> 69 <x-auth-session-status class="mb-4" :status="session('status')" /> 70 71 <form wire:submit="login"> 72 @csrf 73 <!-- Email Address --> 74 <div> 75 <x-input-label for="email" :value="__('Email')" /> 76 <x-text-input wire:model="email" id="email" class="block mt-1 w-full" type="email" name="email" required 77 autofocus autocomplete="username" /> 78 <x-input-error :messages="$errors->get('email')" class="mt-2" /> 79 </div> 80 81 <!-- Password --> 82 <div class="mt-4"> 83 <x-input-label for="password" :value="__('Password')" /> 84 85 <x-text-input wire:model="password" id="password" class="block mt-1 w-full" type="password" name="password" 86 required autocomplete="current-password" /> 87 88 <x-input-error :messages="$errors->get('password')" class="mt-2" /> 89 </div> 90 91 <!-- Remember Me --> 92 <div class="block mt-4"> 93 <label for="remember" class="inline-flex items-center"> 94 <input wire:model="remember" id="remember" type="checkbox" 95 class="rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800" 96 name="remember"> 97 <span class="ml-2 text-sm text-gray-600 dark:text-gray-400">{{ __('Remember me') }}</span> 98 </label> 99 </div> 100 101 <div class="flex items-center justify-end mt-4"> 102 @if (Route::has('password.request')) 103 <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" 104 href="{{ route('password.request') }}" wire:navigate> 105 {{ __('Forgot your password?') }} 106 </a> 107 @endif 108 109 <x-primary-button class="ml-3"> 110 {{ __('Log in') }} 111 </x-primary-button> 112 </div> 113 </form> 114 </div>