Slow Ajax and Login Validation without running right

Asked

Viewed 211 times

0

Good night,

I have a form where I before accessing I do the validation with an ajax, php and mysql, this validation checks the access attempts, and if the user put 5 times the wrong password, it blocks the access for 30 minutes, each session it makes an input in the table "tab_log_try", even if the user is blocked, the problem is that it is not bringing the correct ip... Other than that when I click the enter button it calls the ajax while it is validating, only the problem is validating forever and simply does not call the screen home which is the main, only when I update the page then yes it enters the screen home, I’ve been over this code 500 times and I can’t... If you can help me, I appreciate it. My code is like this:

My table of user:

CREATE TABLE usuario (
   id int(11) NOT NULL AUTO_INCREMENT,
   nome varchar(50) DEFAULT NULL,
   login varchar(30) DEFAULT NULL,
   senha varchar(50) DEFAULT NULL,
   acesso varchar(20) DEFAULT NULL,
   PRIMARY KEY (id)
 ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

logins access table tab_log_try:

CREATE TABLE tab_log_tentativa (
   id int(11) NOT NULL AUTO_INCREMENT,
   ip varchar(15) DEFAULT NULL,
   login varchar(100) DEFAULT NULL,
   senha varchar(300) DEFAULT NULL,
   origem varchar(300) DEFAULT NULL,
   bloqueado char(3) DEFAULT NULL,
   data_hora timestamp NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (id)
 ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

Form page index php.:

<?php
session_start();

if(isset($_SESSION['logado']) &&  $_SESSION['logado'] == 'SIM'):
  header("Location: home.php");
endif;
?>

<!DOCTYPE html>
<html>
<head>
    <title>Exemplo Login com AJAX</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <style type="text/css">
    #login-alert{
        display: none;
    }

    .margin-top-pq{
        margin-top: 10px;
    }

    .margin-top-md{
        margin-top: 25px;
    }

    .margin-bottom-md{
        margin-bottom: 25px;
    }

    .padding-top-md{
        padding-top: 30px;
    }
    </style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>  
</head>
<body>

    <div class="container">    
        <div id="loginbox" class="mainbox col-md-7 col-md-offset-3 col-sm-8 col-sm-offset-2 margin-top-md">                    
            <div class="panel panel-primary" >
                <div class="panel-heading">
                    <div class="panel-title">Login - DevWilliam</div>
                </div>     

                <div class="panel-body padding-top-md" >
                    <div id="login-alert" class="alert alert-danger col-sm-12">
                        <span class="glyphicon glyphicon-exclamation-sign"></span>
                        <span id="mensagem"></span>
                    </div>      
                    <form id="login-form" class="form-horizontal" role="form" action="login.php" method="post">             
                        <div class="input-group margin-bottom-md">
                            <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
                            <input type="login" class="form-control" id="login" name="login" required placeholder="Informe seu Login">                                        
                        </div>

                        <div class="input-group margin-bottom-md">
                            <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
                            <input type="password" class="form-control" id="senha" name="senha" required placeholder="Informe sua Senha">
                        </div>

                        <div class="form-group margin-top-pq">
                            <div class="col-sm-12 controls">
                                <button type="button" class="btn btn-primary" name="btn-login" id="btn-login">
                                  Entrar
                                </button>
                            </div>
                        </div> 

                    </form>     
                </div>  

            </div>  
        </div>
    </div>  

    <script src="js/custom.js"></script>   
</body>
</html>

My js with ajax called custom js.:

$('document').ready(function(){

    $("#btn-login").click(function(){
        var data = $("#login-form").serialize();

        $.ajax({
            type : 'POST',
            url  : 'login.php',
            data : data,
            dataType: 'json',
            beforeSend: function()
            {   
                $("#btn-login").html('Validando ...');//fica validando sempre e não chama a home.php (só quando atualiza a pagina ai entra)
            },
            success :  function(response){                      
                if(response.codigo == "1"){ 
                    $("#btn-login").html('Entrar');
                    $("#login-alert").css('display', 'none')
                    window.location.href = "home.php";
                }
                else{           
                    $("#btn-login").html('Entrar');
                    $("#login-alert").css('display', 'block')
                    $("#mensagem").html('<strong>Erro! </strong>' + response.mensagem);
                }
            }
        });
    });

});

My call validation page login.php:

<?php
session_start();

// Constante com a quantidade de tentativas aceitas
define('TENTATIVAS_ACEITAS', 5); 

// Constante com a quantidade minutos para bloqueio
define('MINUTOS_BLOQUEIO', 30); 

// Require da classe de conexão
require 'configuracao.php';


// Dica 1 - Verifica se a origem da requisição é do mesmo domínio da aplicação

if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] != "http://localhost:8080/contax/index.php"):
    $retorno = array('codigo' => '0', 'mensagem' => 'Origem da requisição não autorizada!');
    echo json_encode($retorno);
    exit();
endif;

// Instancia Conexão PDO
$conexao = Conexao::getInstance();

// Recebe os dados do formulário
$login = (isset($_POST['login'])) ? $_POST['login'] : '' ;
$senha = (isset($_POST['senha'])) ? $_POST['senha'] : '' ;


// Dica 2 - Validações de preenchimento login e senha se foi preenchido
if (empty($login)):
    $retorno = array('codigo' => '0', 'mensagem' => 'Preencha seu Login!');
    echo json_encode($retorno);
    exit();
endif;

if (empty($senha)):
    $retorno = array('codigo' => '0', 'mensagem' => 'Preencha sua senha!');
    echo json_encode($retorno);
    exit();
endif;

// Dica 4 - Verifica o Tipo de IP que o usuario está usando, mas não quer funcionar
function getUserIP()
{

    $http_client_ip       = $_SERVER['HTTP_CLIENT_IP'];
    $http_x_forwarded_for = $_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote_addr          = $_SERVER['REMOTE_ADDR'];
    $http_cf_connecting_ip = $_SERVER["HTTP_CF_CONNECTING_IP"];

    /* VERIFICO SE O IP partiu do cloudflare*/
    if(!empty($http_cf_connecting_ip)){
        $ip = $http_cf_connecting_ip;
    /* VERIFICO SE O IP REALMENTE EXISTE NA INTERNET */
    }elseif(!empty($http_client_ip)){
        $ip = $http_client_ip;
        /* VERIFICO SE O ACESSO PARTIU DE UM SERVIDOR PROXY */
    } elseif(!empty($http_x_forwarded_for)){
        $ip =$http_x_forwarded_for;
    } else {
        /* CASO EU NÃO ENCONTRE NAS DUAS OUTRAS MANEIRAS, RECUPERO DA FORMA TRADICIONAL */
        $ip = $remote_addr;
    }

    return $ip;
}


$user_ip = getUserIP();//Não quer funcionar

$sql = "SELECT count(*) AS tentativas, MINUTE(TIMEDIFF(NOW(), MAX(data_hora))) AS minutos ";
$sql .= "FROM tab_log_tentativa WHERE ip = ? and DATE_FORMAT(data_hora,'%Y-%m-%d') = ? AND bloqueado = ?";
$stm = $conexao->prepare($sql);
$stm->bindValue(1, $user_ip);//Não funciona pegar o IP
$stm->bindValue(2, date('Y-m-d'));
$stm->bindValue(3, 'SIM');
$stm->execute();
$retorno = $stm->fetch(PDO::FETCH_OBJ);

if (!empty($retorno->tentativas) && intval($retorno->minutos) <= MINUTOS_BLOQUEIO):
    $_SESSION['tentativas'] = 0;
    $retorno = array('codigo' => '0', 'mensagem' => 'Você excedeu o limite de '.TENTATIVAS_ACEITAS.' tentativas, login bloqueado por '.MINUTOS_BLOQUEIO.' minutos!');
    echo json_encode($retorno);
    exit();
endif;


// Dica 5 - Válida os dados do usuário com o banco de dados
$sql = 'SELECT id, nome, senha, login FROM usuario WHERE login = ? AND senha = ? AND acesso = ?';
$stm = $conexao->prepare($sql);
$stm->bindValue(1, $login);
$stm->bindValue(2, $senha);
$stm->bindValue(3, 'Ativo');
$stm->execute();
$retorno = $stm->fetch(PDO::FETCH_OBJ);


// Dica 6 - Válida os dados e chama a sessão
if(!empty($retorno)):
    $_SESSION['id'] = $retorno->id;
    $_SESSION['nome'] = $retorno->nome;
    $_SESSION['login'] = $retorno->login;
    $_SESSION['tentativas'] = 0;
    $_SESSION['logado'] = 'SIM';
else:
    $_SESSION['logado'] = 'NAO';
    $_SESSION['tentativas'] = (isset($_SESSION['tentativas'])) ? $_SESSION['tentativas'] += 1 : 1;
    $bloqueado = ($_SESSION['tentativas'] == TENTATIVAS_ACEITAS) ? 'SIM' : 'NAO';

    // Dica 7 - Grava a tentativa independente de falha ou não
    $sql = 'INSERT INTO tab_log_tentativa (ip, login, senha, origem, bloqueado) VALUES (?, ?, ?, ?, ?)';
    $stm = $conexao->prepare($sql);
    $stm->bindValue(1, $_SERVER['SERVER_ADDR']);
    $stm->bindValue(2, $login);
    $stm->bindValue(3, $senha);
    $stm->bindValue(4, $_SERVER['HTTP_REFERER']);
    $stm->bindValue(5, $bloqueado);
    $stm->execute();
endif;


// Se logado envia código 1, senão retorna mensagem de erro para o login
if ($_SESSION['logado'] == 'SIM'):
    $retorno = array('codigo' => '1', 'mensagem' => 'Logado com sucesso!');
    echo json_encode($retorno);
    exit();
else:
    if ($_SESSION['tentativas'] == TENTATIVAS_ACEITAS):
        $retorno = array('codigo' => '0', 'mensagem' => 'Você excedeu o limite de '.TENTATIVAS_ACEITAS.' tentativas, login bloqueado por '.MINUTOS_BLOQUEIO.' minutos!');
        echo json_encode($retorno);
        exit();
    else:
        $retorno = array('codigo' => '0', 'mensagem' => 'Usuário não autorizado, você tem mais '. (TENTATIVAS_ACEITAS - $_SESSION['tentativas']) .' tentativa(s) antes do bloqueio!');
        echo json_encode($retorno);
        exit();
    endif;
endif;

And finally my connection to the bank called php setting.:

<?php 
 /*  
  * Constantes de parâmetros para configuração da conexão  
  */  
 define('HOST', 'localhost');  
 define('DBNAME', 'login');  
 define('CHARSET', 'utf8');  
 define('USER', 'root');  
 define('PASSWORD', '1234');  

 class Conexao {  

   /*  
    * Atributo estático para instância do PDO  
    */  
   private static $pdo;

   /*  
    * Escondendo o construtor da classe  
    */ 
   private function __construct() {  
     //  
   } 

   /*  
    * Método estático para retornar uma conexão válida  
    * Verifica se já existe uma instância da conexão, caso não, configura uma nova conexão  
    */  
   public static function getInstance() {  
     if (!isset(self::$pdo)) {  
       try {  
         $opcoes = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8', PDO::ATTR_PERSISTENT => TRUE);  
         self::$pdo = new PDO("mysql:host=" . HOST . "; dbname=" . DBNAME . "; charset=" . CHARSET . ";", USER, PASSWORD, $opcoes);  
       } catch (PDOException $e) {  
         print "Erro: " . $e->getMessage();  
       }  
     }  
     return self::$pdo;  
   }  
 }

Summarizing the problem.. ajax does not call the home page.php even though the correct login and password is valid and only if I update the page it enters the home page.php,(if the password and login is wrong it shows that it is wrong, this part works!) and the code does not save the ip in the table.. Besides, it’s taking forever to get on the record. I’d really appreciate it if you could help me...

1 answer

0


Ragnar your code apparently has no errors and I managed to run it with some small modifications. Are they:

  1. I changed of $user_ip = getUserIP(); for $user_ip = $_SERVER['REMOTE_ADDR'];. Look at this question (in English) for more information.
  2. Inseri Ativo manually in the column acesso table, because the logic does not treat empty/null values.

How to identify errors in code (debug)?

  • Is it good practice in ajax requests to treat the error of requests and in your scenario how to do this? Using the method error
  • Another way is also to use browser developer tools (usually F12 key) in the network tab to click the request and open the Response tab

Finally follows your jQuery code changed with the handling of errors:

$('document').ready(function(){
    $("#btn-login").click(function(){
        var data = $("#login-form").serialize();

        $.ajax({
            type : 'POST',
            url  : 'login.php',
            data : data,
            dataType: 'json',
            beforeSend: function()
            {   
                $("#btn-login").html('Validando ...');//fica validando sempre e não chama a home.php (só quando atualiza a pagina ai entra)
            },
            success :  function(response){                      
                if(response.codigo == "1"){ 
                    $("#btn-login").html('Entrar');
                    $("#login-alert").css('display', 'none')
                    window.location.href = "home.php";
                }
                else{           
                    $("#btn-login").html('Entrar');
                    $("#login-alert").css('display', 'block')
                    $("#mensagem").html('<strong>Erro! </strong>' + response.mensagem);
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                // to do exibir alerta amigável para o usuário
                alert('Um erro aconteceu na requisição veja o console F12 para mais detalhes');
                $("#btn-login").html('Entrar');
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            }
        });
    });
});

Completion

Its code has no errors, the false sense of slowness was due to warnings released in its code in the indexes used in $_SERVER within the function to grab the ip of the user that came along with the json response making it invalid for jquery parsea it.

  • That’s right, it worked perfect now, it comes in okay, only the ip doesn’t record at all.. it records with ::1 output on all columns.. I don’t know why this,.... but mto thanks even, I’m learning php now so I’m catching now these facilities of F12 and tals.. mto thanks vlw for the tips..

  • He’s recording ::1 pq is your own host on localhost

  • After I realized kkk.. vlw brother

Browser other questions tagged

You are not signed in. Login or sign up in order to post.