I'm trying to create a simple login system, and right now I want to make it so when a user enters a username, and it doesn't match a session variable (not working with database atm), there should be an error message saying that the account doesn't exist.
I have used jQuery for client side form validation,and now I want to use ajax for executing a php script to check if the username exists (i.e., is equal to the session variable) without reloading the page.
Here is the code:
login.php
<?php
session_start();
$error_msg = null;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (empty($_SESSION['uname'])) {
$error_msg = "Error: account does not exist";
}
else if ($_SESSION['uname'] == $_POST['uname'] &&
$_SESSION['pw'] == $_POST['pw']) {
header("Location: index.php");
}
else if ($_SESSION['uname'] != $_POST['uname']) {
$error_msg = "Error: account does not exist";
}
}
?>
<!DOCTYPE html>
<html lang="sv">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.5/jquery.validate.min.js"></script>
<script src="../js/form-validation.js"></script>
<head>
<title> Login </title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="../css/style.css">
</head>
</html>
<body>
<div class="center" id="login_win">
<!-- htmlspecialchars converts special characters to html entities
which ensures that hackers cannot inject damaging scripts
into the $_SERVER["PHP_SELF"] variable -->
<form action="login_credentials.php"
id="login_form"
method="post"
name="first_form">
<h2>Login</h2>
<?php if(isset($error_msg)) { ?>
<p> <?php echo $error_msg ?> </p>
<?php } ?>
<label for="input_uname" id="uname_label">Username:</label>
<input type="text" name="uname" id="input_uname"
placeholder="Enter username">
<br>
<label for="input_pw" id="pw_label">Password:</label>
<input type="password" name="pw" id="input_pw"
placeholder="Enter password">
<br>
<button type="submit"
id="submit_btn"> Sign in </button>
<div id="not_reg">Not registered?
<a href="signup.php" id="not_reg">Sign up</a>
</div>
</form>
</div>
</body>
css:
body {
background-image: url("nature.jpg");
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;
width: 100%;
height: 100%;
image-rendering: crisp-edges;
}
#login_form, #signup_form {
font-family: Algerian, serif;
color: #355f5f;
font-size: large;
}
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
width: 400px;
height: 325px;
box-shadow: 2px 2px 5px 5px rgba(0,0,0,0.15);
border-radius: 25px;
}
#login_win, #signup_win {
opacity: 85%;
}
form { margin-left: 30px; }
p { display: table-row; }
label {
float: left;
}
input {
height: 25px;
margin-left: 30px;
}
#uname_label { margin-top: 3px; }
#input_username { margin-bottom: 20px; }
#pw_label { margin-top: 50px; }
#input_pw {
margin-top: 47px;
margin-right: 50px;
}
#input_uname-error,
#input_pw-error {
color: crimson;
font-family: Monospaced, serif;
font-size: smaller;
white-space: nowrap;
}
#input_uname-error {
margin-top: -55px;
margin-left: 130px;
}
#input_pw-error {
margin-top: -55px;
margin-left: 130px;
}
.center #login_form h2,
.center #signup_form h2 {
text-align: center;
margin-bottom: 30px;
margin-right: 20px;
}
#input_email {
margin-left: 50px;
}
#submit_btn {
margin-top: 30px;
margin-left: 165px;
font-size: 16px;
}
#not_reg {
margin-top: 30px;
text-align: center;
margin-right: 15px;
}
form-validation.js:
// Wait for the DOM to be ready
$(document).ready(function() {
let data = {};
$('#login_form').submit(function(event) {
event.preventDefault();
})
.validate({
rules: {
uname:
{ minlength: 3, required: true },
pw:
{ required: true, minlength: 5 } },
messages: {
uname: { required: "Please provide a username", },
pw: { required: "Please provide a password", },
},
/* submit to action page when
* the form is valid */
submitHandler: function() {
let login_form = document.getElementById('login_form');
let form_data = new FormData(login_form);
let data_arr = [];
for (const [key, value] of form_data.entries()) {
data_arr[key] = value;
}
$.ajax({
type: "POST",
url: "login.php",
data: { uname : data_arr['uname'], pw : data_arr['pw'] }
})
.done(function(msg) {
alert(msg);
});
}
});
});
As you can see above, in the login.php file I try to first initialize the error message variable, then once the form data is sent back the error message is also assigned a string text, upon which I want the if statement in the form to return true and thus the error message should be printed in the form. So my question is, why doesn't it print, or why doesn't the error message show up in my form? The if statement should be true at that point. What have I missed? Thank you in advance.
I have tried putting the php verification code in different files. I have verified that all the if statements are true until the one that is supposed to print the error message. I was expecting the code to execute the if statement again once the error message variable had been set.
Thanks to the help of David and Barmar, I got it working. I put the php code in its own file, and made sure to echo the error message.
I added a div to my html code: <div id="error_msg"></div>
where I wanted the error message to appear. Then, in the .ajax() method, I added the following code:
success: function(data) {
$("#error_msg").html(data);
}
Which takes the data (that which has been echoed) and turns it into html, (if I understand correctly), and then it is put inside the div, which in turn shows up in my form. :)