jimbob
jimbob

Reputation: 1

Change password using php

I am trying to change the password using php on a small login application. When I submit the form it goes to the Login page correctly with no issues but the password is not changed. I don't see any errors in the code. Not sure if this is a query error or am I doing the variable binding wrong. Any ideas?

<?php
// Initialize variables
$password = $confirm_password = "";
$password_err = $confirm_password_err = "";

// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){

    // Validate password
    if(empty(trim($_POST['password']))){
        $password_err = "Please enter a password.";     
    } elseif(strlen(trim($_POST['password'])) < 6){
        $password_err = "Password must have at least 6 characters.";
    } elseif(!preg_match("#[0-9]+#", trim($_POST['password']))){
        $password_err = "Password must have at least 1 number.";
    } elseif(!preg_match("#[a-z]+#", trim($_POST['password']))){
        $password_err = "Password must have at least 1 lowercase character.";
    } elseif(!preg_match("#[A-Z]+#", trim($_POST['password']))){
        $password_err = "Password must have at least 1 uppercase character.";
    } else{
       $password = trim($_POST['password']);
    }

    // Validate password_confirm
    if(empty(trim($_POST["confirm_password"]))){
        $confirm_password_err = 'Please confirm password.';     
    } else{
        $confirm_password = trim($_POST['confirm_password']);
        if($password != $confirm_password){
            $confirm_password_err = 'Password did not match.';
        }
    }

    if(empty($password_err) && empty($confirm_password_err)) {      
        // Prepare an update statement
        $sql = "UPDATE users SET password = ? WHERE username = ?";

        if($stmt = mysqli_prepare($link, $sql)){
            // Bind variables to the prepared statement as parameters
            mysqli_stmt_bind_param($stmt, "ss", $param_password, $param_username);

            // Set parameters
            $param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash
            $param_username = $username;    

            if(mysqli_stmt_execute($stmt)){
            } else {
                echo "Oops! Something went wrong. Please try again later.";                             
            }
        }
        // Close statement
        mysqli_stmt_close($stmt);
        // Close connection
        mysqli_close($link);    
        // Redirect to logout  
        header("location: logout.php");
    }
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Change Password</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css">
    <style type="text/css">
        body{ font: 14px sans-serif; }
        .wrapper{ width: 350px; padding: 20px; }
    </style>
</head>
<body>
    <div class="wrapper">
        <h2>Change Password</h2>
        <p>Please fill this form to change password.</p>
        <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post" autocomplete="off">
            <div class="form-group <?php echo (!empty($password_err)) ? 'has-error' : ''; ?>">
                <label>New Password:<sup>*</sup></label>
                <input type="password" name="password" class="form-control" value="<?php echo $password; ?>">
                <span class="help-block"><?php echo $password_err; ?></span>
            </div>    
            <div class="form-group <?php echo (!empty($confirm_password_err)) ? 'has-error' : ''; ?>">
                <label>Confirm Password:<sup>*</sup></label>
                <input type="password" name="confirm_password" class="form-control" value="<?php echo $confirm_password; ?>">
                <span class="help-block"><?php echo $confirm_password_err; ?></span>
            </div>
            <div class="form-group">
                <input type="submit" class="btn btn-primary" value="Submit">
                <input type="reset" class="btn btn-default" value="Reset">
            </div>
        </form>
    </div>    
</body>
</html>

This is my login.php:

<?php
// Include config file
require_once 'config.php';

// Define variables and initialize with empty values
$username = $password = "";
$username_err = $password_err = "";

// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){

    // Check if username is empty
    if(empty(trim($_POST["username"]))){
        $username_err = 'Please enter username.';
    } else{
        $username = trim($_POST["username"]);
    }

    // Check if password is empty
    if(empty(trim($_POST['password']))){
        $password_err = 'Please enter your password.';
    } else{
        $password = trim($_POST['password']);
    }

    // Validate credentials
    if(empty($username_err) && empty($password_err)){
        // Prepare a select statement
        $sql = "SELECT username, password FROM users WHERE username = ?";

        if($stmt = mysqli_prepare($link, $sql)){
            // Bind variables to the prepared statement as parameters
            mysqli_stmt_bind_param($stmt, "s", $param_username);

            // Set parameters
            $param_username = $username;

            // Attempt to execute the prepared statement
            if(mysqli_stmt_execute($stmt)){
                // Store result
                mysqli_stmt_store_result($stmt);

                // Check if username exists, if yes then verify password
                if(mysqli_stmt_num_rows($stmt) == 1){                    
                    // Bind result variables
                    mysqli_stmt_bind_result($stmt, $username, $hashed_password);
                    if(mysqli_stmt_fetch($stmt)){
                        if(password_verify($password, $hashed_password)){
                            /* Password is correct, so start a new session and
                            save the username to the session */
                        if($stmt = mysqli_prepare($link)){
                            mysqli_stmt_bind_param($stmt, "ss", $param_username);
                            $param_username = $username;
                            if(mysqli_stmt_execute($stmt)){

                            } else {
                                echo "Oops! Something went wrong. Please try again later.";                             
                            }
                        }
                        session_start();
                        $_SESSION['username'] = $username;      
                        header("location: welcome.php");
                    } else{
                        // Display an error message if password is not valid
                        $password_err = 'You have entered an invalid username or password.';
                    }
                }
            } else{
                // Display an error message if username doesn't exist
                $username_err = 'You have entered an invalid username or password.';
            }
        } else{
            echo "Oops! Something went wrong. Please try again later.";
        }
    }

    // Close statement
    mysqli_stmt_close($stmt);
}

// Close connection
mysqli_close($link);
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css">
    <style type="text/css">
        body{ font: 14px sans-serif; }
        .wrapper{ width: 350px; padding: 20px; }
    </style>
</head>
<body>
<div class="wrapper">
    <h2>Login</h2>
    <p>Please fill in your credentials to login.</p>
    <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post" autocomplete="off">
        <div class="form-group <?php echo (!empty($username_err)) ? 'has-error' : ''; ?>">
            <label>Username:<sup>*</sup></label>
            <input type="text" name="username"class="form-control" value="<?php echo $username; ?>">
            <span class="help-block"><?php echo $username_err; ?></span>
        </div>    
        <div class="form-group <?php echo (!empty($password_err)) ? 'has-error' : ''; ?>">
            <label>Password:<sup>*</sup></label>
            <input type="password" name="password" class="form-control">
            <span class="help-block"><?php echo $password_err; ?></span>
        </div>
        <div class="form-group">
            <input type="submit" class="btn btn-primary" value="Submit">
        </div>
        <p>Don't have an account? <a href="register.php">Sign up now</a>.</p>
    </form>
</div>    
</body>
</html>

Upvotes: 0

Views: 1735

Answers (1)

Zeke
Zeke

Reputation: 1291

The $username variable is never declared so... I don't know where you are getting the username from, but wherever that is, you should use it.

What I get...

I see you wish to use the username as your primary key for updates and everything else. That's cool, not my personal approach, but that's good. Since there is no way I can see so far in your code to get the username for updating, I'll guess you're using either $_SESSION or $_COOKIE.

Whatever the case may be, you should make use of that information to set the variables for your SQL query. Otherwise it will be completely empty, thus the SQL query will actually look something like this:

UPDATE `users` SET `password` = '$2y&scfncekr3kj437hdw8e7' WHERE `username` = ''

And that will do nothing at all.

Suggestion

You should set the parameters (variables) before binding them.

// Set parameters (variables)
$param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash
$param_username = $username; // this should be empty so far... maybe $_SESSION['username'] ??

// Bind parameters to the prepared statement
mysqli_stmt_bind_param($stmt, "ss", $param_password, $param_username);

I'm not saying that the order is a problem, because the fact that $username is never set is, but it's just cleaner to read.

Upvotes: 3

Related Questions