password_verify returning false

A

Anonymous

Guest
I currently have the following PHP code:
Code:
<?php
// Check if the user is currently logged in
if (isset($_SESSION["id"])) {
  // Return a JSON object to indicate the login status
  echo '{"isset": true}';
} else {
  // Database variables
  $serverName = "removed from code";
  $dbUsername = "removed from code";
  $dbPassword = "removed from code";
  $dbName = "removed from code";

  // Login <form> variables
  $inputEmail = $_POST['email'];
  $inputPassword = $_POST['password'];

  // Create connection
  $dsn = 'mysql:dbname='.$dbName.';host='.$serverName.';charset=utf8mb4';
  $db = new PDO($dsn, $dbUsername, $dbPassword);
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

  try {
    // Select 1 row, but all columns from the [users] table by the username column
    $stmt = $db->prepare("SELECT * FROM users WHERE email=:email LIMIT 1");

    // Parameterize the query
    $stmt->bindValue(':email', $inputEmail, PDO::PARAM_INT);

    // Execute the query and return the results into $row
    $stmt->execute();
    $row = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // Ensure that a row was returned
    if (count($row) > 0) {
      // Get just hashed password
      $hashedPassword = $row[0]['password'];

      // Confirm that the hashed username matches input as well
      if(password_verify($inputPassword, $hashedPassword)) {
        // Return the JSON equivalent of what was just queried
        echo json_encode($row);
      } else {
        // Return a JSON object to indicate the invalid login
        echo '{"valid": false, "email": true, "password": false}';
      }
    } else {
      // Return a JSON object to indicate the invalid login
      echo '{"valid": false, "email": false, "password": null}';
    }

    // Explicitly close the connection
    $db = null;
  } catch(PDOException $ex) {
    // debug mode, simply echo the exception
    echo json_encode($ex->getMessage());
  }
}
?>

Whenever I debug the code, the value of $hashedPassword does match that of the value in the database(I copy the value, use control+f in phpMyAdmin, and verify that the desired login matches), however after my AJAX request it always returns the following JSON(from my Else statement):
Code:
{
  "valid": false,
  "email": true,
  "password": false
}

Edit - If I assign a variable to the password_verify outside and then use a conditional statement to check the variable, it will always return a True value. I am so confused.
 
I don't know why you are using FETCH_ALL to get a single user? I would do something like the following:
Code:
<?php

$db = DB::getInstance();
$pdo = $db->getConnection(); // This is just my connection string setup:
/* Setup the Query for reading in login data from database table */
$query = 'SELECT * FROM users WHERE email=:email';



$stmt = $pdo->prepare($query); // Prepare the query:
$stmt->execute([':email' => $inputEmail]); // Execute the query with the supplied user's parameter(s):

$stmt->setFetchMode(PDO::FETCH_ASSOC);
$user = $stmt->fetch();

/*
 * If password matches database table match send back true otherwise send back false.
 */
if (password_verify($inputPassword, $user['password'])) { // $user['password'] is whatever 'password' is in your MySQL Database Table:
        /* I would would also unset $user['password'] before sending to javascript */
        unset($user['password']);
 	output($user);
} else {
        errorOutput(['error' => "Sorry invalid login attempt, please try again!"]);
}

If you are using JSON and I would put a couple of functions at the bottom of the page like this:
Code:
/*
 * If you know you have a control error, for example an end-of-file the output it to the errorOutput() function
 */
function errorOutput($output, $code = 500) {
    http_response_code($code);
    echo json_encode($output);
}

/*
 * If everything validates OK then send success message to Ajax / JavaScript
 */

function output($output) {
    http_response_code(200);
    echo json_encode($output);
}
 
Back
Top