Using Wordpress User Credentials with a php script

2019-09-21 10:20发布

问题:

So I've been working my *%& off for the past two days to try to make this work but I always get stuck at the same part : Comparing the computer password received from the iOS App with the hashed password stored in Wordpress DB.

A little background : Basically just a login page on an ios storyboard sending the email and password the user inputs to a php script that checks if the hashed password linked to the sent email is the same as the hashed version of the sent password.

Swift & iOS is't the problem here, so I'll spare you that code. I'm doing my testing using PostMan to send the HTTP POST Request with the correct parameters :

  • Header --> Content-Type : application/x-www-form-urlencoded
  • Body --> email : email@email.com & password : testpasswd

Now here is the original code for the login page :

<?php

require("Connection.php");
require("SQLDao.php");
$email = htmlentities($_POST["email"]);
$password = htmlentities($_POST["password"]);
$returnValue = array();

echo json_encode("Hello World");

if(empty($email) || empty($password))
{
$returnValue["status"] = "error";
$returnValue["message"] = "There is a missing field";
echo json_encode($returnValue);
return;
}

$dao = new MySQLDao();
$dao->openConnection();
$userDetails = $dao->getUserDetailsWithPassword($email,$password);

if($userDetails) {
  $returnValue["status"] = "Success";
  $returnValue["message"] = "User logged in !";
  echo json_encode($returnValue);
} else {
  $returnValue["status"] = "error";
  $returnValue["message"] = "User not found";
  echo json_encode($returnValue);
}

$dao->closeConnection();

?>

Most of SQLDao.php basically handles the SQL connection functions but also this function :

public function getUserDetailsWithPassword($email, $userPassword)
{
$returnValue = array();
$sql = "select id,user_email from vswp_users where user_email='" . $email . "' and user_pass='" .$userPassword . "'";

$result = $this->conn->query($sql);
  if ($result != null && (mysqli_num_rows($result) >= 1)) {
    $row = $result->fetch_array(MYSQLI_ASSOC);
    if (!empty($row)) {
      $returnValue = $row;
    }
  }
  return $returnValue;
}

But this code obviously checks the sent password to the Wordpress Hashed version, so it always returns false.

Through my research, I found this, but it didn't gave me a working solution :

Research no. 1 : include(phpass.php) + CheckPassword function Where I would have something similar to this :

public function getUserDetailsWithHashedPassword($email, $userPassword)
{
  include_once("../wp-config.php");
  include_once("../wp-includes/class-phpass.php");
  $returnValue = array();
  $query = mysql_query("SELECT * FROM vswp_users WHERE user_email = '$email'");
  $row = mysql_fetch_array($query);

  $wp_hasher = new PasswordHash(8, TRUE);

  $password_hashed = $row['user_pass'];

  $passwordMatch = $wp_hasher->CheckPassword($userPassword, $password_hashed) || $password_hashed == md5($userPassword);

  if ($passwordMatch) {
    echo json_encode("Passwords match");
    $returnValue = TRUE;
  } else {
    echo json_encode("Passwords do not match");
    $returnValue = FALSE;
  }
  return $passwordMatch;
}

But this simply returns the "Hello World" but neither options of the if($passwordMatch) are shown.

I apologize for this long question, hopefully someone can point me towards the right direction to fix this.

Thanks for your help !!

EDIT 1 : Through some testing using echo json_encode("Hello World"); I was able find that basically the script stops after the line --> ERASED SINCE NON-RELEVANT ANYMORE

EDIT 2 : I'm getting close, thanks to CBroe idea, I was able to find more information with proper PHP Reporting. I was able to make it work by putting the hashed password stored in the database directly in the login file as a value of $storedPassword and it worked. But now the only problem I'm facing is that while doing this with mysql, I'm getting the following error : substr() expects parameter 1 to be a string, array given in /[...]/class-phpass.php. It seems like I'm only missing a little something to convert the password from the mysql database to a string version of it. Here is my function :

public function getUserDetailsWithHashedPassword($email, $userPassword)
{
  require_once("/home/[hosting provider directories]/public_html/wp-includes/class-phpass.php");
  $returnValue = array();

  $sql = "select user_pass from vswp_users where user_email='" . $email . "'";
  $result = $this->conn->query($sql);
  if ($result != null && (mysqli_num_rows($result) >= 1)) {
    $row = $result->fetch_array(MYSQLI_ASSOC);
    if (!empty($row)) {
      $storedPassword = $row;
    }
  }
  $wp_hasher = new PasswordHash(8, TRUE);
  $passwordMatch = $wp_hasher->CheckPassword($userPassword, $storedPassword);

  if($passwordMatch === TRUE) {
    $returnValue = TRUE;
  } else {
    $returnValue = FALSE;
  }
  return $returnValue;
}

Thanks again !!

回答1:

First fetch user details from database. And then check user's hashed password with plain text password.

To fetch user, you can try:

$user = get_user_by( 'email', $email );

Then:

if ( $user && wp_check_password( $userPassword, $user->data->user_pass, $user->ID) ){
    echo json_encode("Passwords match");
    $returnValue = TRUE;
}
else{
    echo json_encode("Passwords do not match");
    $returnValue = FALSE;
}

related references:

wp_check_password

get_user_by



回答2:

I was finally able to make it work. My last problem with the $row was that i didn't specify which array key I wanted to display. Here is working code if anybody ends up here and needs the working solution ! (Obviously [hosting provider directories] is just my internal file-system, change it to yours if need be)

public function getUserDetailsWithHashedPassword($email, $userPassword)
{
  require_once("/home/[hosting provider directories]/public_html/wp-includes/class-phpass.php");
  $returnValue = array();

  $sql = "select user_pass from vswp_users where user_email='" . $email . "'";
  $result = $this->conn->query($sql);
  if ($result != null && (mysqli_num_rows($result) >= 1)) {
    $row = $result->fetch_array(MYSQLI_ASSOC);
    if (!empty($row)) {
      $storedPassword = $row['user_pass'];
    }
  }
  $wp_hasher = new PasswordHash(8, TRUE);
  $passwordMatch = $wp_hasher->CheckPassword($userPassword, $storedPassword);

  if($passwordMatch === TRUE) {
    $returnValue = TRUE;
  } else {
    $returnValue = FALSE;
  }
  return $returnValue;
}