Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

How do you compare a password to a stored password in a database?

Hey, I've been piecing together a database that receives data through an HTML form. At the moment, I'm trying to create the login part. However, I'm having trouble comparing the password the user enters against the stored hashed password in the database.

I'm trying to compare the username AND password

I've yet to create a session when the user successfully logs in

<?php

include("inc/login_query.php");


?>
<!DOCTYPE html>
<html>
    <head>
        <title>LogIn</title>
        <link rel="stylesheet" type="text/css" href="main.css">
    </head>
    <body>

        <div class="inner-form-bg">
                <form action="welcome.php" method="post">
                    <h1 class="form-h1">Member Login</h1>

                    <input type="text"  placeholder="Username:" name="username" class="field-input req" required><br>


                    <input type="password" placeholder="Password:" name="password" class="field-input req" required><br>

                    <button type="submit" class="submit field-input">Submit</button><br>
                    <button type="button" class="field-input new-acc-btn"><a href="signUp.php" class="create-acc">Create Account</a></button>
                </form>
            </div>


    </body>
    <footer>

    </footer>
</html>
<?php

    include("inc/dbconnection.php"); 

    //check for form submission
    if($_SERVER['REQUEST_METHOD'] == 'POST') {

        $errors = array();

        //check for username
        if(empty($_POST['username'])) {
            $errors = "You forgot to enter your Username";
        } else {

        $username = mysqli_real_escape_string($connection, trim($_POST['username']));
        }


         //check for password
        if(empty($_POST['password'])) {
            $errors[] = "You forgot to enter your password";
        } else {

             $password = mysqli_real_escape_string($connection, trim($_POST['password']));
        }

        if(empty($errors)) {


            $sql_login = "SELECT id, username FROM login WHERE username = '$username' AND passcode = SHA1('$password')";


            $result = mysqli_query($connection, $sql_login);

            if(mysqli_num_rows($result) == 1) {

                while($row = mysqli_fetch_assoc($result)) {

                    //store database username and password into new variables
                    $dbusername = $row['username']; // database column heading
                    $dbpassword = $row['passcode']; // database column heading




                } 
                 /*Check username and password submitted by the user against stored username and password*/
                if($username == $dbusername && $password == $dbpassword) {
                    echo "Welcome" . "<br>";
                } else {
                    echo "incorrect username/password" . "<br>";
                }

            } else {

                echo "Account not found" . "<br>";
            }
?>

I keep getting "Account not found" - so this tells me that its not bringing any rows back at all, I assume?

I can't figure out why. Has it to do with the fact the password has been hashed, and I'm comparing the entered value as a non-hashed value?

Thank you

1 Answer

Kevin Korte
Kevin Korte
28,149 Points

It looks to me you are comparing the users plain text password to the hashed password. The only password you should have in the database is the hashed password. You could var_dump those and make sure you are getting out of the database what you are expecting. You should hash the password, and than compare hashed password to hashed password, so you don't or shouldn't have the plain text password on the database side.

Hey, Kevin, thanks for getting back to me. Yeah!, I thought that might be the issue. So where and how would I hash the password that the user enters, so that I can compare it to the database password?

Would it be:

SHA1($password = mysqli_real_escape_string($connection, trim($_POST['password'])));

I'm not sure how to go about it

I var_dumped $password and $dbpassword - the $dbpassword shows a string of 20 characters, but $password shows a string of 40 characters. As if its been hashed twice... I cant seem to find a reason.

I have a login and sign up form that use the exact same name attributes - could that be a reason? are they conflicting with each other?

Thanks

Kevin Korte
Kevin Korte
28,149 Points

How is the password getting hashed in the first place? Are you building off of someone elses code? That will help track this down.

A log in and sign up form that use the same name attributes is fine, since you can only submit one form at a time. You may just want to separate the logic that handles each form, since what you do with a sign up form and login form would be different.

Here is some light reading how PHP suggests you handle passwords: http://php.net/manual/en/faq.passwords.php Knowing how the password is being hashed when signing up will help.

Hey, yeah, I've pieced together the code from a new different sources.

initially, I hashed the password when they're inserted into the database

     $sql_signUp = "INSERT INTO login (username, email, passcode) VALUES('$username', '$email', SHA1('$password'))";

I doubled checked, and the password was hashed and inserted into the database

I then bring back everything in the row that relates to the username the user supplies, and compare it against the database. I then store the username/password from the database and compare them against the supplied username/password

<?php

    include("inc/dbconnection.php"); 

    //check for form submission
    if($_SERVER['REQUEST_METHOD'] == 'POST') {

        $errors = array();

        //check for username
        if(empty($_POST['username'])) {
            $errors = "You forgot to enter your Username";
        } else {

        $username = mysqli_real_escape_string($connection, trim($_POST['username']));
        }


         //check for password
        if(empty($_POST['password'])) {
            $errors[] = "You forgot to enter your password";
        } else {

            $password = mysqli_real_escape_string($connection, trim($_POST['password']));
        }

        if(empty($errors)) {

            $sql_login = "SELECT * FROM login WHERE username = '$username'";

            $result = mysqli_query($connection, $sql_login);

            if(mysqli_num_rows($result) == 1) {


                while($row = mysqli_fetch_assoc($result)) {

                    $dbusername = $row['username'];
                    $dbpassword = $row['passcode'];

                } 

                if($username == $dbusername && $password == $dbpassword) {
                    echo "Welcome " . $username . " you're now logged in" . "<br>";
                } else {
                    echo "incorrect username/password" . "<br>";
                }

            } else {

                echo "Account not found" . "<br>";
            }


        }

    }


?>

when you mentioned about comparing the plain text password against the hashed password, I then tried a few things to hash the password being supplied. I then var_dumped the $dbpassword and $password - the $password showed a string of 40 characters, whereas the $dbpassword showed a string of 20 characters - So I think its hashing the supplied password twice...

This is what I did to turn the plain text password into a hashed version:

$password = sha1(mysqli_real_escape_string($connection, trim($_POST['password'])));