Connection to database works, but I can not enter [closed]

0

I have the following problem with my system:

  

Connects to the database, but does not enter the system. the user query returns the wrong user despite showing the same   results that the database.

Conexion.php

<?php
$file = 'config.ini.php';
$config = parse_ini_file($file, true);
$host = $config['database']['host'];
$user = $config['database']['username'];
$pass = $config['database']['password'];
$schema = $config['database']['schema'];
$encode = $config['database']['encode'];
class conexion extends mysqli

    {
    public

    function __construct($host, $user, $pass, $schema)
        {
        parent::__construct($host, $user, $pass, $schema);
        if (mysqli_connect_error())
            {
            printf("Falló la conexión: %s\n", mysqli_connect_error());
            }else
            {
            echo "conexión exitosa";
            }
        }
    }

$conexion = new conexion($host, $user, $pass, $schema);

mysqli_set_charset( $conexion, $encode);
?>

Connect.php

    <?php
session_start();
/* Verifico que CONECTAR tenga un valor, esto para validar que este activo javascript y que no entraron por ruta forzada */
$conectar =1;

if ($conectar == 1)
    {
    include '__conexion.php';

    include_once 'funciones/passwordLib.php';

    $usuario = $_POST['txtusuario'] ? : '';
    echo "<br>"."usuario ingresado:".$usuario."<br>";
    $contrasena = $_POST['txtcontrasena'] ? : '';
    echo "<br>"."Contraseña ingresada:".$contrasena."<br>";
    $statement = $conexion->prepare("SELECT hash,nivel_id,unidad_id FROM usuarios WHERE usuario=? LIMIT 1");
    echo "var_dump de statement"."<br>";
  var_dump($statement);
    $statement->bind_param('s', $usuario);
    $statement->execute();
    $statement->store_result();
    if ($statement->num_rows === 0)
        {
        $statement->close();
        /* Si no existe el usuario en la BBDD le decimos que algo esta incorrecto */
        echo ('<script>alert("Usuario o contrase\u00f1a incorrecto, vuelva a ingresar");</script>');
       /* echo ("<script>window.location = 'index.php';</script>");*/
        exit;
        }
      else
        {
        $statement->bind_result($contrasena_BD, $nivel_id, $unidad_id);
        echo "Contraseña en la base de datos: <br>".$contrasena_BD;
        echo "Nivel de acceso <br>".$nivel_id;
        echo "Unidad del usuario <br>".$unidad_id;
        while ($statement->fetch())
            {
            if (password_verify($_POST['txtcontrasena'], $contrasena_BD))
                {
                $_SESSION['nivel'] = $nivel_id;
                $_SESSION['conectado'] = true; //esta conectado//
                $_SESSION['usuario'] = $usuario;
                $_SESSION['unidad'] = $unidad_id;
                $_SESSION['inicio'] = time();
                $_SESSION['expira'] = $_SESSION['inicio'] + (10 * 60); //TIEMPO DE SESIÓN//
                if ($nivel_id == 0)
                    {
                    /* Mensaje de bienvenida segun la clase */
                    echo ('<script>alert("Bienvenido al Sistema Automatizado de OMD");</script>');
                  /*  echo ("<script>window.location = 'menu_unidades.php';</script>");*/
                    }
                elseif ($nivel_id == 1)
                    {
                    echo ('<script>alert("Bienvenido al Sistema Automatizado de OMD");</script>');
                   /*   echo ("<script>window.location = 'menu_administradores.php';</script>");         */
                    }
                elseif ($nivel_id > 1)
                    {
                    echo ('<script>alert("Este usuario no corresponde al sistema");</script>');
                  /* echo ("<script>window.location = 'index.php';</script>");*/
                    }
                }
              else
                {
                /* Mensaje cuando la contraseña no coincide */
                echo ('<script>alert("Usuario o contrase\u00f1a incorrecto, vuelva a ingresar");</script>');
                /*echo ("<script>window.location = 'index.php';</script>");*/
                }
            }

        $statement->close();
        }
    }
  else
    {
    /* Mensaje cuando quieren entrar por ruta forzada */
    echo ('<script>alert("No tiene permisos suficientes para acceder a esta parte del sistema");</script>');
   /* echo ("<script>window.location = 'index.php';</script>");*/
    }

?>

Results of conecta.php

   usuario ingresado:e1_1dinf
  Contraseña ingresada:personalz1
var_dump de statement
object(mysqli_stmt)[2]
  public 'affected_rows' => null
  public 'insert_id' => null
  public 'num_rows' => null
  public 'param_count' => null
  public 'field_count' => null
  public 'errno' => null
  public 'error' => null
  public 'error_list' => null
  public 'sqlstate' => null
  public 'id' => null
Contraseña en la base de datos: 
$2y$10$GUv4G8lxvy6eJ9q93UFyFuU8vqbOz1I9w2wvb48vnZZmtBoklrBK6Nivel de acceso 
0Unidad del usuario 
033100000000
  

EXAMPLE OF MINIMUM CODE :

Index.php

<?php
session_start();
?>
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    <form id="index" name="index" method="POST" action="conectarse.php">
    <input type="text" size="25" maxlength="50" name="txtusuario" id="txtusuario">
    <input type="password" size="25" maxlength="20" name="txtcontrasena" id="txtcontrasena">
    <input type="submit" name="entrar" id="entrar" value="Entrar" onclick="validarLOGIN();">
    </body>
    </form>
    </html>

Connect.php

<?php
session_start();
    include '__conexion.php';
    include_once 'funciones/passwordLib.php';
    $usuario = $_POST['txtusuario'] ? : '';
    $contrasena = $_POST['txtcontrasena'] ? : '';
    $statement = $conexion->prepare("SELECT hash,nivel_id,unidad_id FROM usuarios WHERE usuario=? LIMIT 1");
    $statement->bind_param('s', $usuario);
    $statement->execute();
    $statement->store_result();
    $statement->bind_result($contrasena_BD, $nivel_id, $unidad_id);
    while ($statement->fetch())
            {
            if (password_verify($_POST['txtcontrasena'], $contrasena_BD))
                {
                $_SESSION['nivel'] = $nivel_id;
                $_SESSION['conectado'] = true; 
                $_SESSION['usuario'] = $usuario;
                $_SESSION['unidad'] = $unidad_id;
                $_SESSION['inicio'] = time();
                $_SESSION['expira'] = $_SESSION['inicio'] + (10 * 60);
                }
              else
                {
         echo "Usuario Incorrecto";
                              }
            }

        $statement->close();

    }
?>

The system should then go to your menu, but it shows the passwords as incorrect, apparently it could be password_verify

    
asked by Victor Alvarado 21.04.2017 в 14:08
source

1 answer

1

The question comes from another question that has been the subject of several comments. The problem, as many times is the starting point, the approach that is given to the use of the connections to the database and then, consequently, to the way of consulting it.

I will try to answer the question, although I recognize that MySQLi does not like me for several reasons already explained in other answers and the problem presented here confirms it to me. Anyway, I see that people insist on using MySQLi instead of PDO, or it will be that MySQLi gives too many problems and that is why we see few questions regarding PDO. It can be.

Well, let's make an effort to answer in general . But to not complicate, go to point 3.

1st Treat your connection well

For this the best thing is a class dedicated to the connection to the database.

Simple example of a class using MySQLi:

Modify values such as host, user, etc.

<?php

class SQLiDb  {
    private $host = 'localhost';
    private $user = 'root';
    private $pass = '';
    private $db = 'example';
    private $myconn;

    function connect() {
        $con = mysqli_connect($this->host, $this->user, $this->pass, $this->db);
        if (!$con) {
             //die('Imposible conectar'); //die no me gusta, lo siento
              return NULL;
        } else {
            $this->myconn = $con;
            echo 'Conexión exitosa!';}
        return $this->myconn;
    }

    function close() {
        mysqli_close($myconn);
        echo 'Conexión cerrada';
    }

}

2º Using the connection anywhere

The good thing about having our connection class is that we can use it anywhere. As it is a class, let's use the POO style, creating the object with new .

include_once ("tu-arcivo-de-conexion.php");
$db=new SQLiDb();

// Para verificar si hay conexión no hay que hacer nada más que esto    
if ($db)
{    
//Código con la bd    
}else{
echo "No ha sido posible la conexión";
}

3º Let's go to the specific case that concerns us

Points 1 and 2 are to illustrate a more or less organized way to use the connections.

To try to give a solution to your problem, let's do this:

We assume that the connection works and that you get results in the following way:

//Usemos variables para un código menos confuso
$usuario = $_POST['txtusuario'] ? : '';
$sql = "SELECT hash,nivel_id,unidad_id FROM usuarios WHERE usuario=? LIMIT 1";
$statement->bind_param('s', $usuario);
$statement->execute();
$statement->store_result();

//Olvidemos por ahora el dichoso num_rows

while($data = mi_fetchassoc($statement))
{ 

/*
 * Había olvidado esto
*/
        $contrasena_BD=$data["hash"];
        $nivel_id=$data["nivel_id"];
        $unidad_id =$data["unidad_id"];
/*
 * ***********************************************
*/

        if (password_verify($_POST['txtcontrasena'], $contrasena_BD))
        {
            //Todo el código que haga falta
            $_SESSION['nivel'] = $nivel_id;
            $_SESSION['conectado'] = true; 
            $_SESSION['usuario'] = $usuario;
            $_SESSION['unidad'] = $unidad_id;
            $_SESSION['inicio'] = time();
            $_SESSION['expira'] = $_SESSION['inicio'] + (10 * 60);
         }
          else
         {
           echo "Usuario Incorrecto";
         }
}

//Esto lo usabas mal y lo hacías dentro del while
$statement->free();

//Cerramos la conexión
$conexion->close();

/*
    * Una función personalizada
    * para obtener un arreglo asociativo del resultado
    * Esta misma función nos sirve para saber si hubo resultados
    * Pues devuelve NULL si no hay datos y podemos evaluarla
    * en cualquier parte del código usando algo como
    * if mi_fetchassoc($statement){hay datos}else{no hay datos}
*/  

function mi_fetchassoc($stmt)
{
    if($stmt->num_rows>0)
    {
        $rs = array();
        $md = $stmt->result_metadata();
        $params = array();
        while($field = $md->fetch_field()) {
            $params[] = &$rs[$field->name];
        }
        call_user_func_array(array($stmt, 'bind_result'), $params);
        if($stmt->fetch())
            return $rs;
    }

    return null;
}
    
answered by 21.04.2017 в 16:23