input('role') === 'siswa') { // ...maka validasi input 'nisn' dan 'password'. return [ 'nisn' => ['required', 'string'], 'password' => ['required', 'string'], ]; } // Jika tidak (untuk 'guru' dan 'penjaga perpus') return [ 'nip' => ['required', 'string'], 'password' => ['required', 'string'], ]; } /** * Mencoba untuk mengautentikasi kredensial dari request. * Ini adalah "otak" dari proses login yang berisi logika paling penting. * * @throws \Illuminate\Validation\ValidationException */ public function authenticate(): void { $this->ensureIsNotRateLimited(); $roleDariForm = $this->input('role'); $loginIdentifier = $this->input('nisn') ?: $this->input('nip'); $password = $this->input('password'); $errorField = $this->filled('nisn') ? 'nisn' : 'nip'; if (!Auth::attempt(['nomor_induk' => $loginIdentifier, 'password' => $password], $this->boolean('remember'))) { RateLimiter::hit($this->throttleKey()); throw ValidationException::withMessages([ $errorField => trans('auth.failed'), ]); } $user = Auth::user(); // Cek jika role sesuai if ($user->role !== $roleDariForm) { Auth::logout(); $this->session()->invalidate(); $this->session()->regenerateToken(); RateLimiter::hit($this->throttleKey()); $actualRole = Str::title($user->role ?? 'Tidak Dikenal'); throw ValidationException::withMessages([ 'forbidden' => "Akses ditolak. Akun ini terdaftar sebagai {$actualRole}.", ]); } // Cek jika akun di-banned if ($user->is_banned) { Auth::logout(); $this->session()->invalidate(); $this->session()->regenerateToken(); throw ValidationException::withMessages([ 'forbidden' => "Akun Anda telah dinonaktifkan. Silakan hubungi admin.", ]); } RateLimiter::clear($this->throttleKey()); } /** * Memastikan request login tidak dibatasi karena terlalu banyak percobaan. */ public function ensureIsNotRateLimited(): void { // Jika percobaan belum melebihi 5 kali, lanjutkan. if (!RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { return; } // Jika sudah lebih dari 5 kali, lemparkan error 'throttle'. event(new Lockout($this)); $seconds = RateLimiter::availableIn($this->throttleKey()); throw ValidationException::withMessages([ 'email' => trans('auth.throttle', [ 'seconds' => $seconds, 'minutes' => ceil($seconds / 60), ]), ]); } /** * Mendapatkan kunci throttle untuk request ini. * Kunci ini unik untuk setiap pengguna (berdasarkan nisn/email) dan alamat IP. */ public function throttleKey(): string { // Gunakan 'nisn' jika ada, jika tidak, gunakan 'email' sebagai identitas. $loginIdentifier = $this->input('nisn') ?: $this->input('nip'); return Str::transliterate(Str::lower($loginIdentifier) . '|' . $this->ip()); } }