Using ajax in my case, can it bring some security flaw? If so, how do I solve it? javascript:
$(function() {
if($('#login_submit').length !== 0) {
$('#login_submit').on('click', function() {
if(!$('#login_submit').hasClass('disabled')) {
$.ajax({
url: url + 'login/ajaxLogin',
type: 'POST',
data: $('#login_form').serialize(),
success: function(result) {
alert(result);
$("#login_submit").removeClass("m-progress disabled");
}
});
return false;
}
});
}
});
Controller:
class Login extends Controller {
public function index() {
//if($this->model->isUserLoggedIn())
//header('Location: ' . URL . 'me');
$news = $this->model->latestNews();
require APP . 'view/_templates/header.php';
require APP . 'view/login/index.php';
require APP . 'view/_templates/footer.php';
}
/**
* AJAX-ACTION: AjaxLogin
* TODO documentation
*/
public function ajaxLogin() {
$errors = $this->model->doLoginWithPostData($_POST['user_email'], $_POST['user_password']);
echo $errors;
}
}
Model:
public function doLoginWithPostData($user_email, $user_password) {
if(empty($user_email) AND empty($user_password)) {
return MESSAGE_ALL_EMPTY;
} else if(empty($user_email)) {
return MESSAGE_USERNAME_EMPTY;
} else if(empty($user_password)) {
return MESSAGE_PASSWORD_EMPTY;
} else {
$result_row = $this->getUserData(trim($user_email));
if(!isset($result_row->id)) {
return MESSAGE_USER_DOES_NOT_EXIST;
} else if(($result_row->user_failed_logins >= 3) && ($result_row->user_last_failed_login > (time() - 30))) {
return MESSAGE_PASSWORD_WRONG_3_TIMES;
} else if(!password_verify($user_password, $result_row->password)) {
$sth = $this->db->prepare('UPDATE users '
. 'SET user_failed_logins = user_failed_logins+1, user_last_failed_login = :user_last_failed_login '
. 'WHERE mail = :user_email');
$sth->execute(array(':user_email' => $user_email, ':user_last_failed_login' => time()));
return MESSAGE_PASSWORD_WRONG;
} else {
// write user data into PHP SESSION [a file on your server]
$_SESSION['user_id'] = $result_row->id;
$_SESSION['user_name'] = $result_row->username;
$_SESSION['user_email'] = $result_row->mail;
$_SESSION['user_logged_in'] = 1;
// reset the failed login counter for that user and set last ip and time
$query = $this->db->prepare('UPDATE users '
. 'SET user_failed_logins = 0, user_last_failed_login = NULL, last_online = :time, ip_last = :ip '
. 'WHERE id = :user_id AND user_failed_logins != 0');
$query->execute(array(':time' => time(), ':ip' => $this->getUserIP(), ':user_id' => $result_row->id));
if(defined('HASH_COST_FACTOR')) {
if(password_needs_rehash($result_row->password, PASSWORD_DEFAULT, array('cost' => HASH_COST_FACTOR))) {
$user_password_hash = password_hash($user_password, PASSWORD_DEFAULT, array('cost' => HASH_COST_FACTOR));
$query = $this->db->prepare('UPDATE users SET password = :user_password_hash WHERE id = :user_id');
$query->bindValue(':user_password_hash', $user_password_hash, PDO::PARAM_STR);
$query->bindValue(':user_id', $result_row->id, PDO::PARAM_INT);
$query->execute();
}
}
}
}
}