0

Tengo en la base de datos la contraseña con hash, y con el login envio la password por post. El problema es que al compararlas el password_verify da resultado false y no entiendo porque. El $password enviado por post es sergio, y la contraseña con hash en la base de datos tambien es sergio.

function comprobarUsuario($usuario, $contraseña)
{
$conn = conectarBD();
try {
    $sql = "SELECT username, Password from usuarios where username = '$usuario'";
    $stmt = $conn->query($sql,PDO::FETCH_ASSOC);
    
    $passwordBBDD=$stmt->fetch();// Obtiene la siguiente fila de un conjunto de resultados
                                                var_dump($passwordBBDD);
    if (!$stmt || $stmt->rowCount()!=1) {
        return false;
    } else {
        if (password_verify($contraseña, $passwordBBDD['Password'])) {//Esto resulta false, corregir
            $conn = null;
            return true;
        } else {
           echo $contraseña;
           echo "<br>".$passwordBBDD['Password'];
            return false;
        }
    }
} catch (PDOException $ex) {
    die("Error: ". $ex->getMessage());
}

}

Sergio
  • 41
  • 5
  • ¿Qué muestra el `var_dump` que tienes en el código? ¿Hiciste hash al insertar? Por otra parte, no deberías confiar en `rowCount()` para consultas `SELECT`, el [Manual de PHP](https://www.php.net/manual/es/pdostatement.rowcount.php) te lo dice con toda claridad: *Si la última sentencia SQL ejecutada por el objeto PDOStatement asociado fue una sentencia SELECT, algunas bases de datos podrían devolver el número de filas devuelto por dicha sentencia. Sin embargo, este comportamiento no está garantizado para todas las bases de datos y no debería confiarse en él para aplicaciones portables.* – A. Cedano Sep 07 '21 at 14:30
  • El var dump muestra: array(2) { ["username"]=> string(7) "Bartolo" ["Password"]=> string(20) "$2y$10$g1IzEME9gLm3O" }. Quitaré la parte del rowcount . Para insertar utilizo password_hash($password, PASSWORD_DEFAULT); – Sergio Sep 07 '21 at 14:44
  • Verifica esto directamente: `var_dump(password_verify($contraseña, $passwordBBDD['Password']));` y si muestra `false` entonces ya hablaremos. Todo el rollo de código que estás usando sólo arroja confusión e impide ver el problema real. – A. Cedano Sep 07 '21 at 14:51
  • Devuelve bool(false). Es una simple funcion para comprobar el usuario – Sergio Sep 07 '21 at 15:09

1 Answers1

0

Tu función es algo confusa e insegura. Te propongo que implementes este código, donde su usará una consulta preparada que evite la inyección SQL y el resultado de la verificación se haga mediante una variable $mStatus. Si sigue sin funcionar, podremos ampliar la respuesta a un array con mensajes específicos para saber en qué punto está retornando false. A veces las contraseñas no se verifican porque se está recogiendo la misma incorrectamente, o porque el campo de la contraseña en sí mismo no está definido adecuadamente.

function comprobarUsuario($usuario, $mPassword)
{
    $conn = conectarBD();
    if ($conn) {
      try {
            $sql = "SELECT username, Password from usuarios where username=:username";
            if ($stmt = $conn->prepare($sql)) {
                  $stmt->bindParam(':username', $usuario, PDO::PARAM_STR);
                  $stmt->execute();   
                  $mData=$stmt->fetch(PDO::FETCH_ASSOC);
                  $conn=null;
                  $outPut=array(
                                'status'=>password_verify($mPassword,$mData['Password']),
                                'msg'=>'Ok'
                              );
            } else {
                  $outPut=array('status'=>false, 'msg'=>'Error prepare');
            }
      } catch (PDOException $ex) {
            $outPut=array('status'=>false, 'msg'=>$ex->getMessage());
            return $outPut;
      }
    } else {
        $outPut=array('status'=>false, 'msg'=>'No conexión');
    }
    return $outPut;
}
A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • Sigue dando false, le añadí "if($mStatus == true) { return true; }else{ return false; }" pero tambien da false – Sergio Sep 07 '21 at 15:29
  • Lo que no entiendo es porque da false el password verify, la función la he cogido de otro proyecto que tengo y funciona. – Sergio Sep 07 '21 at 15:36
  • @Pepe prueba la función con el nuevo código (he puesto mensajes específicos en cada parte). Así podrás saber con mayor claridad por dónde está entrando el código y hacer una depuración más específica. Intenta así y dinos qué retorna la función usando un `var_dump` en la llamada de la misma. – A. Cedano Sep 07 '21 at 19:40
  • Muchas gracias A.Cedano, ya lo arreglé se trataba de un error en el tipo de codificacion en la base de datos. Gracias – Sergio Sep 08 '21 at 21:47
  • @Pepe es correcto. A veces falla por problermas de codificación o porque defines una columna de menor tamaño para el hash que se debe guardar, lo cual lo deja truncado haciendo que no coincida... por eso precisamente hablaba de una depuración más específica para explorar esas posibilidades. Para evitar futuros problemas con la codificación considera todas las etapas mencionadas en [esta respuesta](https://es.stackoverflow.com/a/59510/29967). – A. Cedano Sep 08 '21 at 21:52