Issue
I have a login system on my website where someone can create an account, then logout and then log back in. A message displays when a user tries to log into an account that doesn't exist. "Email/Username combination is incorrect". The problem I am having is that this message is displaying even when the account does exist.
Here is index.php
<!DOCTYPE html>
<?php
session_start();
if(isset($_SESSION['username'])) {
header("Location: home.php");
$_SESSION["success"] = "You are now logged in";
}
?>
<html>
<head>
</head>
<body>
<form action="verify_registration_form.php" method="post">
<br>
<input type="username" id="user_name" name="user_name" placeholder="Username" required>
<br><br><br><br><input type="password" id="user_pass_word" name="user_pass_word" placeholder="Password" required>
<br><br><br><br><input type="email" id="user_email" name="user_email" placeholder="Email" required>
<br><br><br><br><input type="submit" class="submit_registration_form_button" id="submit_registration_form_button" name="submit_registration_form_button" value="Sign Up">
</form>
<form action="verify_login_form.php" method="post">
<input type="username" id="user_email_login" name="user_email_login" placeholder="Email" required>
<input type="password" id="user_pass_word_login" name="user_pass_word_login" placeholder="Password" required>
<input type="submit" class="submit_user_login_form_button" id="submit_user_login_form_button" name="submit_registration_form_button" value="Log In">
</form>
</body>
</html>
Here is home.php
<!DOCTYPE html>
<?php
session_start();
if(!isset($_SESSION['username'])) {
header('Location: index.php');
}
?>
<html>
<head>
</head>
<body>
<?php
echo $_SESSION["success"];
?>
<?php if (isset($_SESSION['username'])) : ?>
<p>Welcome <?php echo $_SESSION['username']; ?>
<br><br>
<form action="logout.php" method="post">
<input type="submit" id="logoutbutton" name="logoutbutton" class="logoutbutton" value="Logout">
</form>
<?php endif ?>
</body>
</html>
Here is verify_login_form.php
<!DOCTYPE html>
<?php
session_start();
if($_SERVER['REQUEST_METHOD'] != 'POST') {
header("Location: index.php");
}else{
$connection = mysqli_connect("localhost", "root", "", "websiteusers");
if(!$connection) {
echo "Could not connect to MYSQL database";
}else{
echo "Sucessfully connected to MYSQL database";
$connection = mysqli_connect("localhost", "root", "", "websiteusers");
$useremail = mysqli_real_escape_string($connection,
$_POST["user_email_login"]);
$userpassword = mysqli_real_escape_string($connection,
$_POST["user_pass_word_login"]);
$query = "SELECT * FROM websiteusers WHERE UserEmail='$useremail' AND UserPassWord='$hasheduserpassword'";
$results = mysqli_query($connection, $query);
if(mysqli_num_rows($results) == 1) {
$_SESSION['username'] = $username;
$_SESSION['success'] = "You are now logged in";
header("Location: home.php");
}else{
echo "Email/Username combination is incorrect";
}
}
}
?>
<html>
<head>
</head>
<body>
</body>
</html>
Solution
You can't compare hashed passwords directly. You need to use password_verify instead. Change your code to something like:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli("localhost", "root", "", "websiteusers");
$db->set_charset("utf8mb4");
$query = "SELECT * FROM websiteusers WHERE UserEmail=?";
$stmt = $conn->prepare($query);
$stmt->bind_param("s", $_POST["user_email_login"]);
$stmt->execute();
$row = $stmt->get_result()->fetch_assoc();
if($row && password_verify($_POST["user_pass_word_login"], $row['UserPassWord'])) {
The reason for this is that password_hash() is using a random salt to enhance the hash security, and the generated hash contains this salt. password_verify() extracts the salt from this hash, and hashes your compared string with the same salt, resulting (if the two passwords are the same) in the same hash, whereas using password_hash() a second time results in a different random salt used, which won't generate the same hash, and thus the compare will fail (thanks @Aurelien for this explanation).
Note that mysqli_real_escape_string is not intended for protecting from SQL injection, and if used for this purpose some day will fail you. You should use prepared statements instead.
Answered By - Nick
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.