Search code examples
phpsystempassword-protection

Php Login System Password Hash & Password Verify


I'm trying to make a login system (already have registration system complete) with password_hash() and password_verify() but it isn't working for me. I've been trying to find an answer this whole morning and yet can't seem to make it work, I've watched codecourse tutorials, read blog posts and nothing. The tutorial I've been following the most is this one.

<!-- login -->
<?php
if($_SERVER['REQUEST_METHOD'] == "POST") {
    $errors = array();
    error_reporting(E_ALL); 
    ini_set('display_errors', 1);

    //Basic validation
    if(empty($_POST['username'])){
        $errors[] = "Please enter your username";
        }else{
        $username = $mysqli->real_escape_string($_POST['username']);
        }

            if(empty($_POST['password'])){
            $errors[] = "Please enter your password";
            }else{
            $password = trim($_POST['password']);
            }

            if (empty($errors)) {
            $sql = "SELECT * FROM users WHERE username = '$username'";
            $result = $mysqli->query($sql);
            if ($result->num_rows === 1) {
            $row = $result->fetch_array(MYSQLI_ASSOC);
            if(password_verify($password, $row['password'])) {
                echo 'test';
            $_SESSION['user']['user_id'] = $row['user'];
            header("Location: google.com");
            exit();
            }else{
            $errors[] = "The username or password do not match";
            }
            }else{
            $errors[] = "The username or password do not match";
            }
        }
}
?>

<!-- register -->
<?php
    if($_SERVER['REQUEST_METHOD'] == "POST") {
        $username = mysqli_real_escape_string($conn, $_POST['username']);
        $password = $_POST['password'];
        $hashed_password = password_hash($password, PASSWORD_DEFAULT);
        $confirm_password = mysqli_real_escape_string($conn, $password);
        $ip = $_SERVER['REMOTE_ADDR'];

        if(empty($username) || empty($password) || empty($confirm_password)) {
            $error = "Fill in the missing fields";
        } else {
            $sql = "INSERT INTO users VALUES('', '$username', '$hashed_password', '$ip', 'User')";
            if($conn->query($sql) === TRUE) {
                $error = "Your account has been created.";
            } else {
            $error = "Your account has not been created, please try again later.";  
        } 
    }
}
?>

The end result product is supposed to login in successfully and redirect, I'm using PHP 5.6 and running on localhost XAMPP.


Solution

  • You'll never get a match because you're using

     $password =mysqli_real_escape_string($conn, $_POST['password']); 
    

    to store the password and then not using it on verification. Instead you use

    $password = trim($_POST['password']);
    

    Make sure you don't escape passwords or use any other cleansing mechanism on them before hashing. Doing so changes the password and causes unnecessary additional coding. The password_hash() function can generate some very lengthy text (the current default is 60 characters), so make sure the field in your database is large enough to accommodate the hash. Setting the field larger now will allow for the length needed. The PHP team is adding more algorithms to the method which means the hash can and will grow.