reCaptcha-暴力保护(php/codeIgniter)

reCaptcha-暴力保护(php/codeIgniter),php,codeigniter,security,recaptcha,brute-force,Php,Codeigniter,Security,Recaptcha,Brute Force,当对同一用户名的失败尝试大于5时,我正在登录表单中添加一个reCaptcha字段。 我在没有饼干的情况下很难做到这一点。如果有人有想法,欢迎 这是我的伪代码: 用户进入页面,计数器设置为失败\登录=0 尝试登录时,如果用户猜测用户名正确,但密码错误,则此用户名的db字段将增加 当计数器>5时,在登录页面上显示验证码 我的问题是,即使计数器大于5,我的控制器也不会验证captcha字段。而且,用户可能只是离开我的网站,然后回来让它的计数器返回到0。不使用cookie就可以做到这一点吗?我想有一个

当对同一用户名的失败尝试大于5时,我正在登录表单中添加一个reCaptcha字段。 我在没有饼干的情况下很难做到这一点。如果有人有想法,欢迎


这是我的伪代码:
  • 用户进入页面,计数器设置为失败\登录=0
  • 尝试登录时,如果用户猜测用户名正确,但密码错误,则此用户名的db字段将增加
  • 当计数器>5时,在登录页面上显示验证码

    我的问题是,即使计数器大于5,我的控制器也不会验证captcha字段。而且,用户可能只是离开我的网站,然后回来让它的计数器返回到0。不使用cookie就可以做到这一点吗?我想有一个简单的方法。若我使用cookie,可能会检查用户是否在不久前清除了他的cookie,并显示验证码,有什么想法吗

    我将在下面发布我的完整代码

    控制器

    public function index()
    {
        $data['publickey'] = "6LczHPd2USAAAAAbffN2Po1HaNqPyfdfdfdfdsRfaDPO9E-"; // for reCaptcha
    
        $this->form_validation->set_error_delimiters('<div class="alert alert-danger">', '</div>');
    
        $this->form_validation->set_rules('email', 'lang:label_email', 'required');
        $this->form_validation->set_rules('password', 'lang:label_password', 'required');
    
    
        global $nb_failed_attempt;
        $data['show_captcha'] = FALSE;
    
    
        if ($this->form_validation->run() === FALSE)
        {
            $this->load->view('templates/header', $data);
            $this->load->view('templates/topMenu', $data);
            $this->load->view('pages/login', $data);
    
        }
        else
        {
            #check login
            $success = $this->User_model->checkLogin($this->input->post('email'), $this->input->post('password'));
    
            #sucess redirect to home page
            if ($success) {
                redirect('/');
            }
            # bad login, reload page with error message
            else {
    
                echo $nb_failed_attempt;  ## variable not defined even when it is global inside user_model.php?
    
                if ($nb_failed_attempt > 5) {
                    $data['show_captcha'] = TRUE;
                    $this->form_validation->set_rules('recaptcha_challenge_field', 'Challenge', 'trim|required|callback_captcha_check');
                    # this doesnt get triggered even when >5, no captcha filled and with good pw you can still login..
                }
                else {
                    $data['show_captcha'] = FALSE;
                }
    
                $this->load->view('templates/header', $data);
                $this->load->view('templates/topMenu', $data);
                $this->load->view('pages/login', $data);
            }
        }
    }
    
    
    public function captcha_check($string) {
    
        $privatekey = "6LczHPUSAAAAAKQ58YZoV8S8ZCZ6A4ZiuqxSbbK5";
        $resp = recaptcha_check_answer ($privatekey,
                $_SERVER["REMOTE_ADDR"],
                $_POST["recaptcha_challenge_field"],
                $_POST["recaptcha_response_field"]);
    
        if (!$resp->is_valid) {
            $this->form_validation->set_message('captcha_check', 'The reCAPTCHA wasn\'t entered correctly. Go back and try it again.');
            return FALSE;
        } else {
            return TRUE;
        }
    }
    

    你可以不用饼干就用。有些方法是使用检查表中的远程IP和所有IP并计数,或者只为
    用户名设置计数器,而不检查cookie或IP

    $nb\u失败\u尝试
    index()
    函数是否为全局变量?如果不是-您的答案(
    $nb\u尝试失败
    并非每次都设置)

    UPD

    checkLogin()
    的开头应该是这样的:

    global $nb_failed_attempt;
    $query1 = $this->db->get_where ( 'user', array ('email' => $email), 1, 0 );
    $nb_failed_attempt = $query1->first_row ()->failed_attempt;
    if(@!$nb_failed_attempt)
        $nb_failed_attempt = 0;
    
    global $nb_failed_attempt;
    
    index()
    的开头应该是这样的:

    global $nb_failed_attempt;
    $query1 = $this->db->get_where ( 'user', array ('email' => $email), 1, 0 );
    $nb_failed_attempt = $query1->first_row ()->failed_attempt;
    if(@!$nb_failed_attempt)
        $nb_failed_attempt = 0;
    
    global $nb_failed_attempt;
    
    如果echo$nb\u尝试失败,请检查错误消息并写入工作

    UPD2

    我在大型项目中使用以下会话表结构:

    CREATE TABLE IF NOT EXISTS `session` (
        `id` bigint AUTO_INCREMENT,
        `login` char(128),
        `ip` char(128),
        `try` smallint,
        `blocktime` datetime,
        `sitesession` char(128),
        `firsttime` datetime,
        `lasttime` datetime,
        PRIMARY KEY (`id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=1;
    
    它有助于保存有关登录、输入和帮助用户支持的其他信息


    这个表可能不太好,但对我来说很有用。

    嗯,我想我在这里遗漏了一些东西,我不知道如何在不使用cookie的情况下存储与我的用户相关的变量$nb\u failed\u尝试。顺便说一下,我正在使用代码点火器会话系统:让我们看看。如果(!isset($nb\u失败\u尝试))
    条件始终为真。你们能给问题添加数据库结构吗?如果使用PHP>=5.3.0,函数
    checkLogin
    将生成警告或错误。如果(!isset($nb\u失败\u尝试))
    ,请阅读有关在条件
    之前尝试添加DB查询以选择
    $nb\u失败\u尝试的更多信息。这会像cookies一样工作。谢谢,我不知道引用传递会被弃用,我会修改我的代码,这样我就不用它了。仍在努力使这一切顺利进行。。将更新代码我现在在我的DB请求方法中设置变量$nb_failed_trunt,但即使是全局变量,控制器也会抱怨:“消息:未定义变量:nb_failed_trunt”。如果(!isset($nb\u失败\u尝试))您有
    {
    在您的索引控制器中-但是
    $nb_failed_尝试
    在此之前不会出现。它在哪里设置?这将始终评估为未按当前方式设置。当有人登录几次时,您不应检查“确切的机器”,而应检查“用户”。如果有人以“john”身份登录,则每次登录失败,您都应在failed_logins mysql列上设置计数器+。如果failed_logins>5,则显示验证码,如果登录成功,则重置计数器。对于数据库中的每个用户,都要执行此过程。我不知道如何在codeigniter上执行此操作,但解决方案的草图应该会有所帮助:)。