I am adding a reCaptcha field in my login form when failed attempt on the same username is > 5. I'm having problem doing this without cookies. If someone has an idea, it is welcome.
Here is my pseudo code :
The problem I have is that even when the counter is > 5, the captcha field is not verified by my controller. And also, A user may just leave my site and come back to have it's counter back to 0. Is this possible to do without using cookie? I would like to have a simple way. If I use cookie, maybe check if user has cleared his cookie not too long ago, and display a captcha, any idea welcome https://www.dropbox.com/s/30mf4ha1rm7w407/still_login.png
I'll post my full code below
Controller :
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;
}
}
User_Model (db request)
public function checkLogin($email, $password) {
global $nb_failed_attempt;
if (!isset($nb_failed_attempt)) {
$nb_failed_attempt = 0;
}
#retrieve the user salt
$query1 = $this->db->get_where ( 'user', array ('email' => $email), 1, 0 );
if ($query1->num_rows () <= 0) {
$this->messages->add ( sprintf ( lang ( 'error_log_in' ), 'not_exist' ), "error" );
return false;
}
else {
if ($query1->first_row ()->confirm_code != 'y') {
$this->messages->add ( sprintf ( lang ( 'error_log_in' ), 'not yet activated' ), "error" );
return false;
}
}
$salt = $query1->first_row ()->salt;
// check for hashed password
$saltedPW = $password . $salt;
$hashedPW = hash ( 'sha256', $saltedPW );
$query2 = $this->db->get_where ( 'user', array ('email' => $email, 'password' => $hashedPW), 1, 0 );
### FAILED LOGIN ATTEMPT, increase failed_attempt value
if ($query2->num_rows () <= 0) {
$this->messages->add ( sprintf ( lang ( 'error_log_in' ), 'bad_pwd' ), "error" );
$nb_failed_attempt = $query1->first_row ()->failed_attempt + 1;
$data = array ('failed_attempt' => $nb_failed_attempt );
$this->db->where('email', $email);
$this->db->update('user', $data);
return false;
}
######## Reset failed login attempt if need be #######
if ($query2->first_row ()->failed_attempt > 0) {
$nb_failed_attempt = 0;
$data = array ('failed_attempt' => $nb_failed_attempt );
$this->db->where('email', $email);
$this->db->update('user', $data);
}
######### Save info into cookies #########
$this->session->set_userdata ( array (
'id_user' => $query2->first_row ()->id,
'email' => $query2->first_row ()->email,
'first_name' => $query2->first_row ()->first_name,
'last_name' => $query2->first_row ()->last_name,
'display_name' => $query2->first_row ()->display_name,
'birthdate' => $query2->first_row ()->birthdate,
'sex' => $query2->first_row ()->sex,
'weight' => $query2->first_row ()->weight,
'height' => $query2->first_row ()->height
) );
return true;
}
Here is my table "User":
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(150) NOT NULL,
`password` varchar(255) NOT NULL,
`failed_attempt` int(3) unsigned DEFAULT 0,
`salt` varchar(255) NOT NULL,
`confirm_code` varchar(255),
`reset_token` varchar(255) NOT NULL,
`reset_token_expire` datetime DEFAULT NULL,
`session_id` varchar(255) NOT NULL,
`first_name` varchar(50) NOT NULL,
`last_name` varchar(50) NOT NULL,
`display_name` varchar(50) NOT NULL,
`birthdate` date NOT NULL,
`sex` char(1) NOT NULL,
`last_ip` varchar(50) NOT NULL,
`last_login` datetime DEFAULT NULL,
`date_signup` datetime DEFAULT NULL,
`os` varchar(25) NOT NULL,
`weight` decimal(5,2) unsigned DEFAULT NULL,
`height` decimal(5,2) unsigned DEFAULT NULL
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ;