0

I have a question, after using this stack post to solve a password_verify issue: How to use password_verify function in PHP

Say I have this login form:

<?php
    session_start();
    if ($_SERVER['REQUEST_METHOD'] == 'GET') { ?>
        <form id="signin_frm" name="signinFrm" action="<?php echo htmlentities($_SERVER['SCRIPT_NAME']) ?>" method="post">
            <label class="label-first" for="email">Email</label>
            <input id="email" type="email" name="login_email" placeholder="Someone@example.com" required>
            <label for="pswd">Password</label>
            <input id="pswd" type="password" name="login_password" placeholder="Password" required>
            <fieldset>
                <input class="btn" type="submit" value="Sign-Up">
            </fieldset>
        </form>
<?php } else {
    $email = $_POST['login_email'];
    $password = $_POST['login_password'];
    $find_pswd = "SELECT password FROM UserLogin WHERE email = '$email';";
    $query = mysqli_query($link, $find_pswd);

    while ($row = mysqli_fetch_array($query)) {
        $user_pass = $row['password'];
        $verify_pass = password_verify($password, $user_pass);
    }

    if ($verify_pass === false) {
        echo "Invalid Password";
    }

    mysqli_free_result($query);
}
?>

If, through the mysql query, I am already retrieving a singular value from the table, why is it necessary to use the While Loop in order for password verification to work (verify_password() returning true)? Is there not a simpler way of doing this?

Prior to implementing the while loop, I had this:

<?php } else {
        $email = $_POST['login_email'];
        $password = $_POST['login_password'];
        $find_pswd = "SELECT password FROM UserLogin WHERE email = '$email';";
        $query = mysqli_query($link, $find_pswd);
        $pswd_fetch = mysqli_fetch_array($query);
        if (password_verify($password, $pswd_fetch) === false) {
            echo "Invalid Password";
        }

        mysqli_free_result($query);
    }
?>

Thank you! Aside from this question, feel free to provide any other suggestions in improving this code. I am looking to keep the login fairly simple, as I am only providing the user means to editing information that is not highly sensitive.

NOTE: The password in the database is hashed (BCrypt). Thanks to those who mentioned hashing!

Community
  • 1
  • 1
  • 3
    it's not necessary, unless you allow multiple records with the same email address in your db. if you copied this code from elsewhere, you need to realize that huge quantities of bad php code exist out there, full of crap quality cargo-cult programming garbage. – Marc B Feb 01 '16 at 20:31
  • 1
    A while loop really doesn't make sense, but you should check whether a row was found or not. – martinstoeckli Feb 01 '16 at 20:32
  • [Your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) Learn about [prepared](http://en.wikipedia.org/wiki/Prepared_statement) statements for [MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php). – Jay Blanchard Feb 01 '16 at 20:37

3 Answers3

1

If your not encrypting your passwords you should only need to query the table for the username and password it should return a count of 1. See my code below this is what I used before i started hashing my passwords.

<?php
$host="127.0.0.1"; // Host name 
$username="root"; // Mysql username 
$password="password"; // Mysql password 
$db_name="db_name"; // Database name 
$tbl_name="tbl_name"; // Table name 

// Connect to server and select database.
$con=mysqli_connect("$host","$username","$password","$db_name");
// Check connection
if (mysqli_connect_errno())
{
 echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

// username and password sent from form 
$myusername=$_POST['myusername']; 
$mypassword=$_POST['mypassword']; 

// To protect MySQL injection (more detail about MySQL injection)
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysqli_real_escape_string($con, $myusername);
$mypassword = mysqli_real_escape_string($con, $mypassword);
$result = mysqli_query($con,"SELECT * FROM $tbl_name
WHERE username='$myusername' and password='$mypassword'");

// Mysql_num_row is counting table row
$count=mysqli_num_rows($result);

// If result matched $myusername and $mypassword, table row must be 1 row
if($count==1)
{
 session_start();
 // Register $myusername, $mypassword and redirect to file "stud.php" 
 $_SESSION['myusername'] = $myusername;
 $_SESSION['mypassword'] = $mypassword;
 header("location:stud.php");
 exit();
}
else 
{
 header("location:main_login_error.php");
 exit();
}
mysqli_close($con);
?>
Tracy McCormick
  • 401
  • 1
  • 7
  • 18
  • The OP *is* hasing the passwords, hence the usage of `password_verify()`. – Jay Blanchard Feb 01 '16 at 20:47
  • 1
    Plus, if this errors out `echo "Failed to connect to MySQL: " . mysqli_connect_error();` that'll throw a headers sent notice, due to the placement of `session_start();`. Edit: *Isn't that right Sam?* @JayBlanchard ;-) – Funk Forty Niner Feb 01 '16 at 21:24
0

Like Marc B said, you don't need to have a While loop.

It's also a good idea to escape user entered data before querying the DB just to avoid injection, if someone wishes to do hard to your website/database.

 $email = mysqli_real_escape_string($_POST['login_email']);

You could also instead of doing this:

if ($_SERVER['REQUEST_METHOD'] == 'GET')

You could have:

if(!isset($_POST)){ 
     //Show form 
 } 
  else { 
     //Query DB With POST details
  }
Rizo
  • 54
  • 8
  • 1
    Btw, this will fail `mysqli_real_escape_string($_POST['login_email'])` - Do read the manual on that http://php.net/manual/en/mysqli.real-escape-string.php `string mysqli_real_escape_string ( mysqli $link , string $escapestr )` – Funk Forty Niner Feb 01 '16 at 21:31
  • Plus, their use of `if ($_SERVER['REQUEST_METHOD'] == 'GET')` is specific, if someone tried to use a GET method, it would call up their form which is using a POST method. – Funk Forty Niner Feb 01 '16 at 21:34
  • The "if ($_SERVER['REQUEST_METHOD'] == 'GET')" actually comes from the book 'PHP Cookbook' by David Sklar & Adam Trachtenberg. – tylerptmusic Feb 01 '16 at 23:23
0

Thank you for the inputs I have received thus far. This was simply for confirmation and clarification since I was only relying one other post to provide me with help. Since there were two comments confirming that the While Loop is not needed in the case of retrieving one value, I went back and replaced this:

while ($row = mysqli_fetch_array($query)) {
    $user_pass = $row['password'];
    $verify_pass = password_verify($password, $user_pass);
}

with this:

$row = mysqli_fetch_array($query);
$user_pass = $row['password'];
$verify_pass = password_verify($password, $user_pass);

and everything works fine. I will take all the other suggestions regarding the code in general (such as the code to avoid injections) into consideration as I refine this file, as I still need to add code for $_SESSION methods and such. If this post still allows it, I will accept any further suggestions if necessary.

Thanks again!