diff --git a/login.php b/login.php new file mode 100644 index 0000000..b317033 --- /dev/null +++ b/login.php @@ -0,0 +1,507 @@ + 5, // 登录尝试次数限制 + 'block_time' => 15 * 60, // 封锁时间(秒) + 'check_interval' => 60 * 60, // 检查时间窗口(秒) + 'ip_blacklist_file' => __DIR__ . '/data/ip_blacklist.txt', + 'login_attempts_file' => __DIR__ . '/data/login_attempts.json' +]; + + +$antiSpamDir = dirname($antiSpamConfig['login_attempts_file']); +if (!file_exists($antiSpamDir)) { + mkdir($antiSpamDir, 0777, true); +} + +// 获取客户端IP地址 +function getClientIP() { + if (isset($_SERVER['HTTP_CLIENT_IP'])) + return $_SERVER['HTTP_CLIENT_IP']; + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) + return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]; + return $_SERVER['REMOTE_ADDR']; +} + +// 检查IP是否在黑名单中 +function isIPBlacklisted($ip, $blacklistFile) { + if (!file_exists($blacklistFile)) return false; + + $blacklist = file($blacklistFile, FILE_IGNORE_NEW_LINES); + return in_array($ip, $blacklist); +} + +// 记录登录尝试 +function logLoginAttempt($ip, $success, $config) { + $attempts = []; + $file = $config['login_attempts_file']; + + // 读取现有记录 + if (file_exists($file)) { + $json = file_get_contents($file); + $attempts = json_decode($json, true) ?: []; + } + + // 添加新记录 + $attempts[] = [ + 'ip' => $ip, + 'time' => time(), + 'success' => $success + ]; + + // 只保留指定时间窗口内的记录 + $threshold = time() - $config['check_interval']; + $attempts = array_filter($attempts, function($a) use ($threshold) { + return $a['time'] >= $threshold; + }); + + // 保存记录 + file_put_contents($file, json_encode(array_values($attempts))); + + // 如果失败次数超过限制,将IP加入黑名单 + $ipAttempts = array_filter($attempts, function($a) use ($ip) { + return $a['ip'] === $ip && !$a['success']; + }); + + if (count($ipAttempts) >= $config['login_attempts_limit']) { + addToIPBlacklist($ip, $config['ip_blacklist_file']); + return true; // IP已被封锁 + } + + return false; +} + +// 添加IP到黑名单 +function addToIPBlacklist($ip, $blacklistFile) { + file_put_contents($blacklistFile, $ip . PHP_EOL, FILE_APPEND); +} + +// 检查并处理验证码请求 +if (isset($_GET['get_captcha'])) { + // 可以添加IP请求频率检查 + header('Content-Type: image/png'); + include('verify.php'); + exit; +} + +// 获取客户端IP +$clientIP = getClientIP(); + +// 检查IP是否被封锁 +if (isIPBlacklisted($clientIP, $antiSpamConfig['ip_blacklist_file'])) { + http_response_code(403); + die("您的IP已被封锁,请稍后再试。"); +} + +// 密码哈希加密配置(可选:设置算法参数) +// define('PASSWORD_COST', 12); // 默认10,数值越大越安全但性能消耗越高 + +if ($_SERVER["REQUEST_METHOD"] == "POST") { + $username = trim($_POST["username"]); // 去除首尾空格 + $plainPassword = trim($_POST["pwd"]); // 原始密码(不存储) + $code = trim($_POST["code"]); + + // 输入验证:非空检查 + if (empty($username) || empty($plainPassword) || empty($code)) { + logLoginAttempt($clientIP, false, $antiSpamConfig); + echo ""; + exit(); + } + + // 验证码验证(区分大小写需调整strtolower) + if (strtolower($_SESSION["code"]) !== strtolower($code)) { + logLoginAttempt($clientIP, false, $antiSpamConfig); + echo ""; + exit(); + } + + // 数据库查询:获取用户哈希密码 + $stmt = $connect->prepare("SELECT id, username, password FROM librarian WHERE username=?"); + $stmt->bind_param("s", $username); + $stmt->execute(); + $result = $stmt->get_result(); + + if ($user = $result->fetch_assoc()) { + // 验证密码哈希 + if (password_verify($plainPassword, $user["password"])) { + // 密码正确,更新会话并跳转 + logLoginAttempt($clientIP, true, $antiSpamConfig); + + $_SESSION["user_id"] = $user["id"]; + $_SESSION["username"] = $user["username"]; + $_SESSION["login_time"] = time(); // 记录登录时间(可选) + + // 自动更新哈希版本(可选:若使用旧算法) + // if (password_needs_rehash($user["password"], PASSWORD_DEFAULT, ['cost' => PASSWORD_COST])) { + // $newHashedPassword = password_hash($plainPassword, PASSWORD_DEFAULT, ['cost' => PASSWORD_COST]); + // $updateStmt = $connect->prepare("UPDATE librarian SET password=? WHERE id=?"); + // $updateStmt->bind_param("si", $newHashedPassword, $user["id"]); + // $updateStmt->execute(); + // $updateStmt->close(); + // } + + header("Location: admin_index.php"); + exit(); + } else { + // 密码错误 + logLoginAttempt($clientIP, false, $antiSpamConfig); + $stmt->close(); + echo ""; + exit(); + } + } else { + // 用户不存在 + logLoginAttempt($clientIP, false, $antiSpamConfig); + $stmt->close(); + echo ""; + exit(); + } + + $stmt->close(); +} + +// 退出登录逻辑 +if (isset($_GET['tj']) && $_GET['tj'] == 'out') { + session_destroy(); + header('location: login.php'); + exit; +} +?> + + + + + + 图书后台管理系统登录功能 + + + +
+ 背景1 + 背景2 + 背景3 + 背景4 +
+ +
+
+
+

图书管理后台管理中心

+
+ + + + + + + + + + + + + +
+ +
+ +
+
+ + 验证码 +
+
+ + +
+
+
+
+ + + + + + \ No newline at end of file