password_verify返回false。找不到错误

时间:2018-12-18 03:58:00

标签: php passwords password-protection password-encryption password-hash

大约2个月以来,我一直在试图解决此问题,但似乎无法解决。我有一个返回哈希密码的数据库。由于可以打印所有信息,因此我可以确认这项工作。可以很好地返回未哈希且经过哈希处理的密码,但是当检查密码时,它将始终返回false。

我不确定该怎么办。这可能确实很容易,但是我似乎找不到。

<?php
    session_start();
    $dbip = "localhost";
    $dbuser = "root";
    $dbpass = "";
    $dbname = "projectNitro";
    $conn = new mysqli($dbip, $dbuser, $dbpass, $dbname);

    if($conn->connect_error) {
        echo("Connection failed: " . $conn->connect_error);
    }

    $password = mysqli_real_escape_string($conn, $_GET["pass"]);
    $email = mysqli_real_escape_string($conn, $_GET["email"]);
    $sql = "SELECT * FROM users WHERE email='{$email}' LIMIT 1";
    $query = mysqli_query($conn, $sql);
    $pass = $_GET["pass"];

    if($query == TRUE) {
        $row = mysqli_fetch_array($query);
        $db_password = $row['password'];
        $db_usertype = $row['accountType'];
        $username = $row['username'];
        echo $password;
        echo "<br>";
        echo $db_password;
        echo "<br>";
        $verify = password_verify($pass, $db_password);

        if($verify) {
            $_SESSION['username'] = $username;
            $_SESSION['at'] = $db_usertype;
            header("Location: http://website.com");
        } else {    
            echo("DB Email: "
            .$row["email"]
            ."<br>Username: "
            .$row["username"]
            ."<br>DB Password: "
            .$row["password"]
            ."<br>AccountType: "
            .$row["accountType"]
            ."<br>Inserted Email: "
            .$_GET["email"]
            ."<br>Inserted Password: "
            .$_GET["pass"]."<br>");

            if(password_verify($_GET["pass"], $row["password"])) {
                echo("epic<br>");
            } else {
                echo("not epic<br>");
            }
        }
    } else {
        header("Location: http://website.com");
    }
    $conn->close();
?>

1 个答案:

答案 0 :(得分:1)

您需要执行一些步骤。只要可行,就继续加紧。

这是您的代码的更简单版本,应与官方文档http://php.net/manual/en/function.password-verify.php

中的密码示例一起使用

还使用die();在每个{}块中调试代码。 在您当前的代码中,在两种情况下您都重定向到网站,如果您被重定向,很难跟踪出什么问题了!

您有无用且不清楚的变量,例如$dbpass$db_password非常模棱两可,即使您和我了解它使其无法维护。除了您的编码风格之外,您还需要缩进!

下一步需要检查此代码是否有效,就是用硬编码哈希替换硬编码密码。

<?php

session_start();
$dbip = "localhost";
$dbuser = "root";
$dbpass = "";
$dbname = "projectNitro";
$conn = new mysqli($dbip, $dbuser, $dbpass, $dbname);

if ($conn->connect_error){
  echo("Connection failed: " . $conn->connect_error) . '<br><br>';
}

$password = 'rasmuslerdorf';//mysqli_real_escape_string($conn, $_GET["pass"]);
// $email = mysqli_real_escape_string($conn, $_GET["email"]);
// $sql = "SELECT * FROM users WHERE email='{$email}' LIMIT 1";
// $query = mysqli_query($conn, $sql);
// $pass = $_GET["pass"];

// if ($query == TRUE) {
  // $row = mysqli_fetch_array($query);
  $db_password = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
  // $username = $row['username'];

  echo $password;
  echo "<br>";
  echo $db_password;
  echo "<br>";

  if (password_verify($password, $db_password)) {
    die('ok');
  } else {
    die('not ok');
  }
// } else {
//   header("Location: http://website.com");
// }

$conn->close();
?>

在这里,我做了一些修改,并在代码中添加了一些注释,以帮助您理解该方法。

<?php

session_start();

// This array is used only like a simple namespace.
$dbCredentials = [
  'host' => "localhost",
  'user' => "root",
  'password' => "",
  'dbname' => "projectNitro"
];
$dbConn = new mysqli($dbCredentials['host'], $dbCredentials['user'], $dbCredentials['password'], $dbCredentials['dbname']);

if ($dbConn->connect_error) {
  // Should not continue script if can't connect to DB.
  die("Connection failed: " . $dbConn->dbConnect_error);
}

// You should check the existence of $_GET["pass"] before using it, with empty() or isset().
$passwordToCheck = mysqli_real_escape_string($dbConn, $_GET["pass"]);// Renamed var more meaningful.
$userEmail = mysqli_real_escape_string($dbConn, $_GET["email"]);
$sql = "SELECT * FROM users WHERE email='{$userEmail}' LIMIT 1";// Don't select * if you don't need everything.
$query = mysqli_query($dbConn, $sql);
$pass = $_GET["pass"];// you already have $passwordToCheck.

if ($query) {// Don't need == TRUE
  // $row = mysqli_fetch_array($query);
  $db_password = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
  $username = $row['username'];

  echo "$passwordToCheck<br>$db_password<br>";// This is way less verbose than repeating echo and uses less echo functions.

  if (password_verify($passwordToCheck, $db_password)) {// Don't need to keep this condition in a variable. 
    die('ok');// this is just an example to test.
  } else {
    die('not ok');// this is just an example to test.
  }
} else {
  header("Location: http://website.com");// While debugging don't redirect, put die('message');
}

$dbConn->close();
?>