throttleKey($request); if (RateLimiter::tooManyAttempts($key, self::MAX_ATTEMPTS)) { $seconds = RateLimiter::availableIn($key); $request->session()->forget('captcha'); throw ValidationException::withMessages([ 'email' => '登录尝试过于频繁,出于安全考虑已临时锁定。请在约 '.ceil($seconds / 60).' 分钟('.ceil($seconds).' 秒)后重试。', ]); } $data = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required', 'string'], 'captcha' => ['required', 'string', function ($attribute, $value, $fail) use ($request) { if (strtolower(trim((string) $value)) !== strtolower((string) $request->session()->get('captcha', ''))) { $fail('图形验证码不正确,请重新输入。'); } }], ]); if (! Auth::attempt(['email' => $data['email'], 'password' => $data['password']], $request->boolean('remember'))) { RateLimiter::hit($key, self::DECAY_SECONDS); $attempts = RateLimiter::attempts($key); $left = max(0, self::MAX_ATTEMPTS - $attempts); $request->session()->forget('captcha'); $msg = '账号或密码不正确。'; if ($left > 0) { $msg .= "(已错误 {$attempts} 次,再错 {$left} 次将锁定 10 分钟)"; } else { $msg .= '(错误次数过多,已锁定 10 分钟)'; } return back()->withErrors([ 'email' => $msg, ])->onlyInput('email'); } $user = Auth::user(); if (! $user->isAdmin()) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); $request->session()->forget('captcha'); return back()->withErrors([ 'email' => '该账户没有后台管理权限。', ])->onlyInput('email'); } RateLimiter::clear($key); $request->session()->forget('captcha'); $request->session()->regenerate(); return redirect()->intended('/admin'); } protected function throttleKey(Request $request): string { return 'admin-login:'.strtolower($request->input('email', '')).':'.$request->ip(); } }