​PHP防止被爬虫模拟登录的安全方案

275 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 6 月更文挑战」的第 4 天,点击查看活动详情

随着互联网的不断发展,各种爬虫工具也应运而生。其中,模拟登录成为一种常见的技术手段。通过模拟登录,即可直接获取目标网站的数据,而不必单独爬取。然而,这也带来了一定的安全隐患。今天,我介绍一种PHP的防爬虫模拟登录的安全方案,可有效保护目标网站的安全。

要防止爬虫模拟登录,可以采取一些安全措施来增加系统的安全性。以下是一些PHP中防止被爬虫模拟登录的安全方案:

  1. 使用验证码:在登录表单中添加验证码功能,要求用户在登录时输入验证码。这可以防止大多数自动化脚本和爬虫攻击,因为它们通常无法解析和处理验证码。
  2. 添加延迟和限制尝试次数:在登录失败的情况下,添加延迟或者限制尝试次数。这样可以防止爬虫通过尝试大量的用户名和密码组合来进行暴力破解。可以在每次失败登录尝试后增加延迟,或者在一段时间内限制登录尝试次数。
  3. 强化密码策略:确保用户设置强密码,并使用哈希算法对密码进行加密存储。使用PHP的密码哈希函数(如password_hash)可以安全地存储密码。这样即使爬虫获取到了存储的密码信息,也很难还原出原始密码。
  4. 防止暴力破解:采取一些措施来防止暴力破解攻击。例如,在每次登录尝试失败后,可以在一段时间内锁定帐户或者IP地址。还可以采用更高级的方法,例如实施基于令牌或验证码的限制策略。
  5. 检测异常行为:通过监控登录行为和模式,检测异常行为。例如,检查是否有多个帐户同时从同一个IP地址尝试登录,或者是否有大量的登录尝试来自同一个用户。
  6. 使用HTTPS:使用HTTPS来加密用户的登录信息,防止信息在传输过程中被窃取或篡改。这可以通过在服务器上安装有效的SSL证书来实现。
  7. 封禁恶意IP地址:保持一个黑名单,并将已知的恶意IP地址添加到黑名单中。可以根据恶意活动的模式或者异常行为来自动封禁IP地址。
  8. 引入人机交互:在登录过程中引入人机交互,例如通过实施点击拼图、拖动滑块等操作来验证用户。这可以增加对自动化脚本和爬虫的防护。

以下是一些具体实现代码示例,展示了如何在PHP中应用上述安全方案:

1.使用验证码:

    // 生成验证码
    $randomCode = generateRandomCode(); // 生成随机验证码
    $_SESSION['captcha'] = $randomCode; // 将验证码存储在会话中

    // 在登录表单中添加验证码输入框,并在后端验证
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $captchaInput = $_POST['captcha'];
        if (isset($_SESSION['captcha']) && $captchaInput === $_SESSION['captcha']) {
            // 验证码正确,执行登录逻辑
        } else {
            // 验证码错误,显示错误信息
        }
    }

2.添加延迟和限制尝试次数:

    // 检查登录失败次数
    $loginAttempts = $_SESSION['login_attempts'] ?? 0;

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // 检查登录逻辑,如果登录失败则增加登录失败次数
        if (/* 登录失败 */) {
            $loginAttempts++;
            $_SESSION['login_attempts'] = $loginAttempts;
        }
        
        // 如果登录失败次数过多,增加延迟
        if ($loginAttempts >= 3) {
            sleep(3); // 延迟3秒
        }
        
        // 如果登录失败次数过多,锁定帐户或者IP地址
        if ($loginAttempts >= 5) {
            // 锁定帐户或IP地址的逻辑
        }
    }

3.强化密码策略:

    // 哈希密码并存储
    $password = $_POST['password'];
    $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
    // 将哈希后的密码存储到数据库或其他存储介质中
  1. 防止暴力破解:
    // 检查登录失败次数并锁定帐户或IP地址
    $loginAttempts = $_SESSION['login_attempts'] ?? 0;

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // 检查登录逻辑,如果登录失败则增加登录失败次数
        if (/* 登录失败 */) {
            $loginAttempts++;
            $_SESSION['login_attempts'] = $loginAttempts;
        }
        
        // 如果登录失败次数过多,锁定帐户或IP地址
        if ($loginAttempts >= 5) {
            // 锁定帐户或IP地址的逻辑
        }
    }
  1. 检测异常行为:
// 检测登录行为和模式
$userIP = $_SERVER['REMOTE_ADDR'];
$userAgent = $_SERVER['HTTP_USER_AGENT'];

// 检测同一IP地址尝试多个帐户登录
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 获取尝试登录的帐户信息和登录状态
    $username = $_POST['username'];
    $loginStatus = /* 获取登录状态的逻辑 */;
    
    // 检测是否有多个帐户同时从同一个IP地址尝试登录
    if ($loginStatus === 'failed') {
        $attempts = $_SESSION['login_attempts'] ?? [];
        $attempts[$username] = ($attempts[$username] ?? 0) + 1;
        $_SESSION['login_attempts'] = $attempts;

        $failedAttempts = $attempts[$username];

        // 检测是否有多个帐户同时从同一个IP地址尝试登录
        $ipAttempts = $_SESSION['ip_attempts'] ?? [];
        $ipAttempts[$userIP][$username] = ($ipAttempts[$userIP][$username] ?? 0) + 1;
        $_SESSION['ip_attempts'] = $ipAttempts;

        $ipFailedAttempts = $ipAttempts[$userIP][$username];

        // 根据失败尝试次数进行处理,例如锁定帐户或者IP地址
        if ($failedAttempts >= 5) {
            // 锁定帐户的逻辑
        }

        if ($ipFailedAttempts >= 10) {
            // 锁定IP地址的逻辑
        }
    }
}