莫名
This commit is contained in:
@@ -13,17 +13,17 @@ class AuthController extends Controller
|
||||
{
|
||||
if (is_admin()) { $this->redirect(login_landing()); }
|
||||
$error = '';
|
||||
$blocked = false;
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// 质量红线:登录必须校验 CSRF + 验证码 + IP/会话双重失败限速,杜绝机器人暴力破解
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
|
||||
// 质量红线:登录必须校验 CSRF + 验证码 + IP 级双窗口限速(失败 10 分钟/5 次、成功 30 分钟/5 次),杜绝机器人暴力破解
|
||||
if (!csrf_check()) {
|
||||
$error = '表单已过期,请刷新页面后重试';
|
||||
} elseif (ip_login_blocked($ip)) {
|
||||
$error = '尝试次数过多,请 15 分钟后再试';
|
||||
$error = '尝试次数过多,请 30 分钟后再试';
|
||||
$blocked = true;
|
||||
} elseif (!captcha_check($this->post('captcha'))) {
|
||||
$error = '验证码错误,请重新计算';
|
||||
} elseif ($this->isBlocked()) {
|
||||
$error = '尝试次数过多,请 15 分钟后再试';
|
||||
} else {
|
||||
$u = trim($this->post('username'));
|
||||
$p = $this->post('password');
|
||||
@@ -38,8 +38,7 @@ class AuthController extends Controller
|
||||
$user = ['id' => 0, 'username' => $u, 'name' => '管理员', 'role' => 'super_admin'];
|
||||
}
|
||||
if ($ok) {
|
||||
$this->clearAttempts();
|
||||
ip_login_clear($ip);
|
||||
ip_login_register_success($ip); // 记录成功登录(纳入 30 分钟 5 次上限),并重置失败计数
|
||||
session_regenerate_id(true); // 防会话固定
|
||||
$_SESSION['admin_logged'] = true;
|
||||
$_SESSION['admin_id'] = $user['id'] ?? 0;
|
||||
@@ -52,11 +51,15 @@ class AuthController extends Controller
|
||||
$_SESSION['psi_perms'] = $dec($user['psi_perms'] ?? null);
|
||||
$this->redirect(login_landing());
|
||||
}
|
||||
$this->registerAttempt();
|
||||
ip_login_register($ip);
|
||||
ip_login_register_fail($ip); // 记录一次失败(纳入 10 分钟 5 次上限)
|
||||
$error = '用户名或密码错误';
|
||||
}
|
||||
}
|
||||
// 被限速(IP 失败/成功过多)时返回 429 + Retry-After,明确告知客户端稍后再试
|
||||
if ($blocked && !headers_sent()) {
|
||||
http_response_code(429);
|
||||
header('Retry-After: ' . ip_login_remaining($ip));
|
||||
}
|
||||
$captcha = captcha_make(); // 每次渲染都发放新的算术验证码
|
||||
return $this->view('admin/login', ['error' => $error, 'captcha' => $captcha]);
|
||||
}
|
||||
@@ -68,25 +71,6 @@ class AuthController extends Controller
|
||||
&& \Core\App::config('app.driver', 'file') !== 'mysql';
|
||||
}
|
||||
|
||||
/** 暴力破解限速:单会话 15 分钟内失败 5 次即锁定 */
|
||||
private function isBlocked(): bool
|
||||
{
|
||||
$t = $_SESSION['login_attempts'] ?? null;
|
||||
if (!$t || ($t['time'] + 900) < time()) return false;
|
||||
return $t['count'] >= 5;
|
||||
}
|
||||
private function registerAttempt(): void
|
||||
{
|
||||
$t = $_SESSION['login_attempts'] ?? ['count' => 0, 'time' => time()];
|
||||
if (($t['time'] + 900) < time()) { $t = ['count' => 0, 'time' => time()]; }
|
||||
$t['count']++;
|
||||
$_SESSION['login_attempts'] = $t;
|
||||
}
|
||||
private function clearAttempts(): void
|
||||
{
|
||||
unset($_SESSION['login_attempts']);
|
||||
}
|
||||
|
||||
/** 修改当前登录账号的密码 */
|
||||
public function password()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user