Php 登录限制和阻止所有IP地址

Php 登录限制和阻止所有IP地址,php,security,throttling,ip-blocking,Php,Security,Throttling,Ip Blocking,我必须限制登录,如果出现大规模失败的尝试,我想阻止所有IP。如何使用下面的代码实现这一点?如果下面的代码不够好,请告知关于这个问题的好教程 <?php $throttle = array(1 => 1, 10 => 2, 1000 => 'captcha'); $getfailedq = 'SELECT MAX(attempted) AS attempted FROM failed_logins'; $getfailed = $muc->prepare($getfa

我必须限制登录,如果出现大规模失败的尝试,我想阻止所有IP。如何使用下面的代码实现这一点?如果下面的代码不够好,请告知关于这个问题的好教程

<?php
$throttle = array(1 => 1, 10 => 2, 1000 => 'captcha');
$getfailedq = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$getfailed = $muc->prepare($getfailedq);
$getfailed->execute();
if ($getfailed->rowCount() > 0) {
    $row = $getfailed->fetch(PDO::FETCH_ASSOC);
    $latest_attempt = (int) date('U', strtotime($row['attempted']));
    $getfailedq = 'SELECT Count(*) AS failed FROM failed_logins WHERE attempted > Date_sub(Now(), INTERVAL 15 minute)';
    $getfailed = $muc->prepare($getfailedq);
    $getfailed->execute();
    if ($getfailed->rowCount() > 0) {
        $row = $getfailed->fetch(PDO::FETCH_ASSOC);
        $failed_attempts = (int) $row['failed'];
        krsort($throttle);
        foreach ($throttle as $attempts => $delay) {
            if ($failed_attempts > $attempts) {
                if (is_numeric($delay)) {
                    $remaining_delay =  time() - $latest_attempt + $delay;
                    echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
                } else {
                    echo "captcha";
                }
                break;
            }
        }        
    }
}
?>

根据您的示例,这主要是伪代码。您可以将
ip
字段添加到
failed\u logins
表中,同时创建一个名为
blocked\u logins
的新表

<?php

// get users IP address
$ip = $_SERVER['REMOTE_ADDR'];

// find out if user has already been blocked
$getblockedq = 'SELECT ip FROM blocked_logins WHERE ip = :ip';
$getblocked = $muc->prepare($getblockedq);
$getblocked->execute(array(':ip' => $ip));
$total = $getblocked->fetchColumn();

if ($total > 0) {
    // user is blocked, do not proceed
}

// find number of failed logins within past 15 mins
$getfailedq = 'SELECT Count(*) AS failed FROM failed_logins WHERE ip = :ip AND attempted > Date_sub(Now(), INTERVAL 15 minute)';
$getfailed = $muc->prepare($getfailedq);
$getfailed->execute(array(':ip' => $ip));
$total = $getfailed->fetchColumn();

if ($total <= 2) {
    // looks good, attempt to login
} elseif ($total <= 10) {
    // you must wait x seconds...
} elseif ($total <= 1000) {
    // display captcha
} else {
    // block user
}

当两个查询中都没有参数时,为什么要绑定参数?这是一个好问题,谢谢,修复了查询
如果($getfailed->rowCount()>0){
这将始终是真的,因此第一个查询是pointless@cmorrissey,对,我该如何解决这个问题?max()将始终返回一行,因此rowcount永远不能为零。您必须获取该max()值并直接测试它。谢谢,但我收到了此错误致命错误:调用未定义的方法PDO::fetchColumn()@Serjio抱歉,这只是用于逻辑的伪代码,而不是语法。请尝试以下方法:
$getblocked->fetchColumn();
我已经更新了我的示例。