Search code examples
phpmysqlpassword-hash

Why is my Log in System not working?


I've created a system which allows a admin to register another admin with an email address and password to log into a protected area. A admin is registered through this form:

<form action="adduser.php" method="POST">
            <label for="emailaddress">Email Address: </label><input type="text" name="emailaddress" />
            <label for="password">Password: </label><input type="password" name="password" />
            <label for="name">Name: </label><input type="text" name="name"/>
            <input type="submit" value="Submit" name="submit"/>
</form> 

The adduser.php looks like this:

<?php
    require'databaselogin.php';
    if(isset($_POST['emailaddress'],$_POST['password'],$_POST['name'])){
        $result= $pdo->prepare('INSERT INTO users (emailaddress, password, name )
                            VALUES(:emailaddress, :password, :name)');
        $hash = password_hash($_POST['password'], PASSWORD_DEFAULT);  
        unset($_POST['submit']);
        $_POST['password'] = $hash;
        $result->execute($_POST);
        header("Location:admin.php");
    }
?>

Up to here appears to work the table called users then gets populated with data. I guess potentially it could be using $hash incorrectly than the password stored in the table isn't what the user entered in the password field?

When the user attempts to log in using this form:

<form action="login.php" method="POST" >
                <label for="emailaddress">Email Address:</label><input type="text" name="emailaddress"/>
                <label for="password">Password:</label><input type="password" name="password"/>
                <input type="submit" value="Go" name="submit"/>
            </form>

Linking to this php:

<?php
    session_start();

        require'databaselogin.php';
            $stmt = $pdo->prepare('SELECT * FROM users WHERE emailaddress = :emailaddress');
            if(isset($_POST['submit'])){
            $criteria = [
            'emailaddress' => $_POST['emailaddress'],
            ];
            $stmt->execute($criteria);

            $user = $stmt->fetch();
            var_dump($user);
            if (password_verify($_POST['password'], $user['password'])) {
                $_SESSION['loggedin'] = $user['id'];
                header("Location:admin.php");
            }
            else {
                header("Location:index.php");
            }
            }
?> 

With the correct email and password entered into the registration from the website just reloads on index.php rather than taking them to admin.php. I really can't understand the issue here as the code looks sound too me I'm guessing it's an issue with whatever $hash is actually saving to the password field.

If someone can help with this it'd be really appreciated!


Solution

  • Since you're not responding to comments, I am submitting the following.

    I suspect that your password column's length is too short.

    If that is the case, you need to set it at 60+. So, ALTER your column, clear your password rows that contain hashes, create a new hash and try again.

    The manual on this:

    PASSWORD_DEFAULT - Use the bcrypt algorithm (default as of PHP 5.5.0). Note that this constant is designed to change over time as new and stronger algorithms are added to PHP. For that reason, the length of the result from using this identifier can change over time. Therefore, it is recommended to store the result in a database column that can expand beyond 60 characters (255 characters would be a good choice).

    • MySQL will fail silently if it is too short. I have seen that happen many times before.

    On an added note:

    It's best to use exit; after each header, otherwise your code may want to continue to execute.

    if (password_verify($_POST['password'], $user['password'])) {
        $_SESSION['loggedin'] = $user['id'];
        header("Location:admin.php");
        exit;
    }
    else {
        header("Location:index.php");
        exit;
    }