Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Why password_verify Function Not Passing the Verification in PHP Application?

    • 0
    • 0
    • 0
    • 1
    • 0
    • 0
    • 0
    • 1.53k
    Answer it

    Php Programmers,

     

    Why does the password_verify keep failing ? I checked the myql tbl column name (passwords) and there is no typo.

    The $query is able to get the $result querying the db ($result = true).

    The password_verify is in this format:

     

    password_verify(User Input Password, Password found in DB).

    [code]

    if (password_verify($password, (string)$row['passwords']))

    [/code]

     

    I type casted the 2nd param of password_verify because it was giving error before:

     

    Fatal error: Uncaught TypeError: password_verify() expects parameter 2 to be string, null given in /home/user/public_html/php/login.php:64 Stack trace: #0 /home/user/public_html/php/login.php(64): password_verify('password', NULL) #1 {main} thrown in /home/luser/public_html/php/login.php on line 64

     

    After type casting the error is gone. But new problem. I get echoed that, the password_verify failed. I created a condition ith the echo to echo that if the password_verify fails:

     

    [code]

    if (password_verify($password, $row['passwords']))

    {

    $_SESSION["user"] = $username;

    header("location:home.php?user=$username"); 

    }

    else

    {

    echo "'password_verify' function failed!";

    exit();

    [/code]

    }

     

     

    Here, the full code:

    [code]

    <?php

     

    /*

    ERROR HANDLING

    */

    declare(strict_types=1);

    ini_set('display_errors', '1');

    ini_set('display_startup_errors', '1');

    error_reporting(E_ALL);

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

     

    include 'config.php';

     

    // check if user is already logged in

    if (is_logged() === true) 

    {

    //Redirect user to homepage page after 5 seconds.

    header("refresh:5;url=home.php");

    exit; //

    }

     

     

    if ($_SERVER['REQUEST_METHOD'] == "POST")

    if (isset($_POST["login_username"]) && isset($_POST["login_password"]))

    {

    $username = trim($_POST["login_username"]); //

    $password = trim($_POST["login_password"]); //

    $hashed_password = password_hash($_POST["login_password"], PASSWORD_DEFAULT);

             

    //Select Username or Email to check against Mysql DB if they are already registered or not.

     

    $stmt = mysqli_stmt_init($conn);

           

    $stmt = mysqli_prepare($conn, "SELECT ids, usernames, passwords, emails, accounts_activations_statuses FROM users WHERE usernames = ?");

    mysqli_stmt_bind_param($stmt, 's', $email);

    mysqli_stmt_execute($stmt);

    $result = mysqli_stmt_bind_result($stmt, $db_id, $db_username, $db_password, $db_email, $db_account_activation_status); // ... this line. But not both.

    $row = mysqli_stmt_fetch($stmt);

     

     

    printf("%s (%s)\n",$row["usernames"],$row["passwords"]);

    echo "var_dump(result)";var_dump($result)?><br><?php //On experiment, this showing as: () bool(true);

     

    if ($result == false)

    {

    echo "Incorrect Login Details!";

    echo "$result == false";

    exit(); 

    }

    elseif ($row['accounts_activations_statuses'] == '0')

    {

    {

    echo "You have not activated your account! Check your email for instructions.";

    exit();

    }

    }

    else

    {

    echo '$result == True'; //for debugging purpose

    echo "'Hashed Password from Data Base:' $db_password<br>"; //for debugging purpose

    }

     

    if (password_verify($password, $row['passwords']))

    {

    $_SESSION["user"] = $username;

    header("location:home.php?user=$username");

    }

    else

    {

    echo "'password_verify' function failed!";

    exit();

    }

    }

    }

     

    ?>

     

    <!DOCTYPE html>

    <html>

    <head>

    <title><?php $site_name?> Login Page</title>

      <meta charset="utf-8">

    </head>

    <body>

    <div class = "container">

    <form method="post" action="">

    <center><h3><?php $site_name ?> Login Form</h3></center>

    <div class="text-danger">

    <div class="form-group">

    <center><label>Username:</label>

    <input type="text" placeholder="Enter Username" name="login_username" value=""</center>

    </div>

    <div class="form-group">

    <center><label>Password:</label>

    <input type="password" placeholder="Enter password" name="login_password" value=""></center>

    </div>

    <div class="form-group">

    <center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center>

    </div>

    </form>

    </div>

    </body>

    </html>

     

    [/code]

     

    What is causing the password_verify to fail the verification ?

 1 Answer(s)

  • Hi,

    It seems the issue was the "passwords" column size was too small (50 chars). Switching it to 255 should have made a difference but it did not in my test last night due to me not repopulating the column. Others in another forum suggested I repopulate and I read their suggestion just now and it is working after I repopulated it. Just sharing this knowledge on all forums I opened threads on this issue so it benefits other newbies too. I know this is nothing "learnable" for pros.
    http://www.webdeveloper.com/forum/showthread.php?366069-Why-password_verify-Not-Passing-The-Verification&p=1516863#post1516863

    And so, this code is no longer getting the password_verify to false when I type the correct password.
    Code:
    [code]
    <?php
     
    /*
    ERROR HANDLING
    */
    declare(strict_types=1);
    ini_set('display_errors', '1');
    ini_set('display_startup_errors', '1');
    error_reporting(E_ALL);
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
     
    include 'config.php';
     
    // check if user is already logged in
    if (is_logged() === true) 
    {
        //Redirect user to homepage page after 5 seconds.
        header("refresh:2;url=home.php");
        exit; //
    }


    if ($_SERVER['REQUEST_METHOD'] == "POST")

        if (isset($_POST["login_username_or_email"]) && isset($_POST["login_password"]))
        {
            $username_or_email = trim($_POST["login_username_or_email"]); //
            $password = $_POST["login_password"];
            
             
            //Select Username or Email to check against Mysql DB if they are already registered or not.
            $stmt = mysqli_stmt_init($conn);
            
            if(strpos("$username_or_email", "@") === true)
            {
                $email = $username_or_email;
                $username = "";
                
                $query = "SELECT ids, usernames, passwords, emails, accounts_activations_statuses FROM users WHERE emails = ?";
                // i = integer; s = string; d = double; b = blob.
                $stmt = mysqli_prepare($conn, $query);            
                mysqli_stmt_bind_param($stmt, 's', $email);
                mysqli_stmt_execute($stmt);
                //$result = mysqli_stmt_get_result($stmt); //Use either this line (if you need to get all data of the array without associating them to variables like you do with mysqli_stmt_bind_result), or ...
                //Note from line below that the variables "$db_username", "$db_account_activation_status" are related to the tbl columns selected on $query ("SELECT ids, usernames, accounts_activations_statuses From users .. WHERE).
                $result = mysqli_stmt_bind_result($stmt, $db_id, $db_username, $db_password, $db_email, $db_account_activation_status); // ... this line. But not both.
            }
            else
            {
                $username = $username_or_email;
                $email = "";
                $query = "SELECT ids, usernames, passwords, emails, accounts_activations_statuses FROM users WHERE usernames = ?";
                // i = integer; s = string; d = double; b = blob.
                $stmt = mysqli_prepare($conn, $query);
                mysqli_stmt_bind_param($stmt, 's', $username);
                mysqli_stmt_execute($stmt);
                //$result = mysqli_stmt_get_result($stmt); //Use either this line (if you need to get all data of the array without associating them to variables like you do with mysqli_stmt_bind_result), or ...
                //Note from line below that the variables "$db_email", "$db_account_activation_status" are related to the tbl columns selected on $query ("SELECT ids, emails, accounts_activations_statuses From users .. WHERE).
                $result = mysqli_stmt_bind_result($stmt, $db_id, $db_username, $db_password, $db_email, $db_account_activation_status); // ... this line. But not both.#
            }           
            
            //$rownums = mysqli_num_rows($result); // To get number of row matches
            //echo "$rownums";
            //Which of the following to do and why that one over others ?
            $row = mysqli_stmt_fetch($stmt);
            //$row = mysqli_fetch_array($query, MYSQLI_ASSOC);
            //$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
            
            mysqli_stmt_close($stmt);
            
            printf("%s (%s)\n",$row["usernames"],$row["passwords"]);
            
            if ($result == false)
            {
                echo "'$result == false' on line 73! IF got triggered on line 73! !<br>";
                exit();
            }
            elseif ($row['accounts_activations_statuses'] == '0')
            {
                {
                    echo "You have not activated your account yet! Check your email for instructions on how to activate it. 
                    Check your spam folder if you don't find an email from us.";
                    exit();
                }
            }
            else
            {
                echo "'$result == true' on line 73! Else got triggered on line 86! <br>";//This ELSE is getting triggered on the test. That means $result = TRUE;
            }
            
            if (password_verify($password, $db_password))        
            {
                echo "IF triggered for password_verify! password_verify ok";
                //If 'Remember Me' check box is checked then set the cookie. 
                //if(!empty($_POST["login_remember"])) // Either use this line ....
                if (isset($_POST['login_remember']) && $_post['login_remember'] == "on") // ...or this line. But not both!
                {
                    setcookie("login_username", $username, time()+ (10*365*24*60*60));
                }
                else
                {
                    //If Cookie is available then use it to auto log user into his/her account!
                    if (isset($_COOKIE['login_username']))
                    {
                        setcookie("login_username","","");
                    }
                }
                $_SESSION["user"] = $username;
                header("location:home.php?user=$username");                
            }
            else
            {
                echo "Else got triggered on line 111: Incorrect User Credentials ! 'password_verify = FALSE';<br>";
                exit();
            }
        }
    }
        
    ?>

    <!DOCTYPE html>
    <html>
    <head>
    <title><?php $site_name?> Member Login Page</title>
      <meta charset="utf-8">
    </head>
    <body>
    <div class = "container">
    <form method="post" action="">
    <center><h3><?php $site_name ?> Member Login Form</h3></center>
    <div class="text-danger">
    <div class="form-group">
    <center><label>Username/Email:</label>
    <input type="text" placeholder="Enter Username" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center>
    </div>
    <div class="form-group">
    <center><label>Password:</label>
    <input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center>
    </div>
    <div class="form-group">
    <center><label>Remember Login Details:</label>
    <input type="checkbox" name="login_remember" /></center>
    </div>
    <div class="form-group">
    <center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center>
    </div>
    <div class="form-group">
    <center><font color="red" size="3"><b>Forgot your password ?</b><br><a href="login_password_reset.php">Reset it here!</a></font></center>
    <center><font color="red" size="3"><b>Not registered ?</b><br><a href="register.php">Register here!</a></font></center>
    </form>
    </div>
    </body>
    </html>
    [/code]

    I am making a few changes on the above post's mentioned code because I was told in that forum (which I mentioned in my previous post):

    1. Checking if $result is true/false is meaningless, as it will always be true if my code is bug-free, and likely always false if not. 
    2. Similarly, mysqli_stmt_fetch() will return true if it found a result row, otherwise false. 
    I, instead need to check the value bound to $db_password to see if it's correct. So it might be something like:

    [code]
    if($row && password_verify($password, $db_password)) {
    // good to go...

    [/code]

    I have been advised 6 nights ago there on that forum to trim down my code to this:
    [code]
    if ($_SERVER['REQUEST_METHOD'] == "POST") // not really needed since you're checking $_POST
    {
        if (isset($_POST["login_username"]) && isset($_POST["login_password"])) {
            $username = trim($_POST["login_username"]); //
            $password = trim($_POST["login_password"]); //
            $hashed_password = password_hash($_POST["login_password"], PASSWORD_DEFAULT);
            $sql = "
    SELECT
      ids,
      usernames, 
      passwords, 
      emails, 
      accounts_activations_statuses 
    FROM users 
    WHERE usernames = ?
      AND passwords = ?
    ";
            $stmt = mysqli_prepare($conn, $sql);
            mysqli_stmt_bind_param($stmt, 'ss', $username, $hashed_password);
            mysqli_stmt_execute($stmt);
            if (mysqli_stmt_num_rows($stmt)) {
                // found a match, we're good to go...
            } else {
                // whatever you do when user/password not found...
            }
        }
    }
    [/code]

    This forum Mod also managed to figure it that I got the column size wrong:
    https://www.webmastersun.com/threads/18216-why-password_verify-function-not-logging-me-in
Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: