Rather than use the thirdparty phpcodechecker.com I prefer to use PHP’s built in declare(strict_type=1); and error_reporting(_1); because the code just stops until the errors are cleared. Exact details are displayed where the error occurred.
There is a similar error validation script for MySQL which can be obtained from:
@wake689, I’ve never used the hashed password before but I found some good references to follow. @spaceshiptrooper I got the error message working but I got a new error " Cannot modify header information - headers already sent by -snip-** on line 35". This is what is on line 35 header("location: Admin.php"); // redirect user to the Admin.php web page.
I spent a bit of time researching what that was and I couldn’t see any white spaces and just in case, I made sure there were none. At least is not letting me sign in as before!
<?php
session_start();
if (isset($_POST["Login"])) {
checkLogin($_POST["Name"], $_POST["Password"]);
}
function checkLogin($Username, $Password) {
$servername = "localhost";
$DB_username = "User1";
$DB_password = "password";
$stored_password='$2y$12$JjbjqRYzxFO2L4.rcPdW/OcVCR1KUIDCN6DvsIUDFaR7JxKTSMh/2';
try {
$conn = new PDO("mysql:host=" . $servername . ";dbname=e0912343_Fixtures", $DB_username, $DB_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$statement = $conn->prepare("SELECT * FROM Admin WHERE Username= :Username");
$result= $statement->execute(array(':Username'=>':Username'));
if ($result){
if(password_verify('User1', $stored_password)) {
echo "<script> alert('The ID or password entered is not valid. Please enter a valid username and password') </script>";
} else {
echo "Welcome to the Admin Page!";
}
$_SESSION['Name']= $Username;
header("location: Admin.php"); // redirect user to the Admin.php web page
}
}
catch(PDOException $e) {
echo "An error occured: " . $e->getMessage();
}
$conn = null;
}
?>
@wake689, can I please clarify a bit more… “Follow that logic through - if the password does not match, ie the “if” is false”… I’m getting a bit confused because I thought that if the pw didn’t match, the else statement would take over but it seems that it works as “false” first?
@mabismad thank you for your post. I had to read it carefully, there’s lots of information on it. As I mentioned before, I’m new at this, and learning PHP has been a hard but interesting road. There are too many ways of doing the same thing in my opinion and that makes it easier to get off the rails and get confused. I’ve read many articles and watched many videos in order to work on my project. At college, the motto has been to you give you the basics and let you get both immersed and lost in the wild to learn the language and I’m not so sure it’s the right move but I’m not sure which is! In your view, is there a more systematic approach to learn it?
You have corrected that error in your latest code. This was in reply to the code you posted as
if(password_verify($DB_password, $Password)) { // confirming password
echo "The password is correct";
}
$_SESSION['Name']= $Username;
header("location: Admin.php"); // redirect user to the Admin.php web page
}
else {
echo '<script type="text/javascript">alert("The username or password entered is not valid. Please enter a valid username and password")</script>';
}
where you close the action to be taken if the “if” condition is true after the line
echo '<script type="text/javascript">alert("The username or password entered is not valid. Please enter a valid username and password")</script>';
and then after the closing } you set the session variable and sent the user off to Admin.php. But you have corrected that in your latest code.
I would have thought it would be easier to be taught rather than just told to “Google it”! But I don’t know - I am old enough for coding to have not been taught when I was at school.
I taught myself HTML 25+ years ago, when it was just HTML3 and hand coded my first personal website in a text editor (on the Amiga computer). I then came back to web coding about 2 years ago and have been teaching myself HTML5, CSS, PHP, mySQL and a little (only a little, so far!) javascript. I have used a mixture of books, YouTube, Google, forums. I am no kind of expert at all, but I am earlier enough in my learning curve to remember my early mistakes and misunderstandings.
I have a couple of further points to make about your code.
Re password_hash. I’m not sure wether you understand that it works as follows:
password_hash() takes a password as input and then encrypts it and outputs the encrypted password which you then store in your database. This cannot be reverse engineered to obtain the password - no-one can take this encrypted password and work out what the password is.
password_verify() then takes two arguments (“inputs” if you like) - one is this encrypted password, from your database, that was created by password_hash (usually when a user registers) (eg
$2y$12$JjbjqRYzxFO2L4.rcPdW/OcVCR1KUIDCN6DvsIUDFaR7JxKTSMh/2
) and the other is the password entered by the user when attempting to log on (eg ‘MyDogFido123’).
password_verify then passes a result of either true or false, depending on whether the encrypted password matches the plain text password.
That’s why I wondered how you are creating the password that is stored in your database table “Admin”.
My second point is that I think you may be trying to use the database password as the user login password. But no-one else has picked up on this so far so I am beginning to doubt myself a little (but only a little). Are you getting these two sets of passwords/usernames mixed up - the database username/password and the username/password of the person who is trying to login in to your site?
I hope I am explaining things OK here - others will hopefully chime in to say whether this is indeed a mistake that you are making or whether I have got this wrong.
Alright, it seems too many people are giving you pointers which is probably overwhelming you. And the links being thrown into the mix probably makes it worse. Taking bits of everything all of us are telling you and mixing it which most likely won’t work and further the confusion. This is why I only mentioned the password_verify() portion of it. Otherwise, I’d give you more information.
So I’m just going to help you fix the header error and let others help you since there’s too many cooks in the kitchen.
To solve the header problem, the reason why it happens is there is output after a header() function. This includes not just white spaces, but other various things like HTML, CSS, Javascript, etc. This is generally why I use if-else instead of just if. To get things started, I’d suggest putting all your data selection and $_POST related items within an if statement of $_SERVER['REQUEST_METHOD']. Then everything like your HTML related items in the else part of the statement.
Here’s a small sample just to get started.
if($_SERVER['REQUEST_METHOD'] == 'POST') {
// Put all of your database and logic stuff here.
} else {
// Put all of your HTML stuff here.
}
@wake689, thanks for the password_hash explanation. I understand that better now! And no, I named the password “DB_password” for the user on purpose, so that I wouldn’t confused it with the actual database password. I thought it was a good idea at the time! This user only has privileges to view, edit and delete data on one table in the database. My question on the “IF” was more so on how to read to sound out the logic properly to follow what it was doing
<?php
session_start();
if (isset($_POST["Login"])) {
checkLogin($_POST["Name"], $_POST["Password"]);
}
function checkLogin($Username, $Password) {
$servername = "localhost";
$DB_username = "User1";
$DB_password = "password";
$stored_password='$2y$12$JjbjqRYzxFO2L4.rcPdW/OcVCR1KUIDCN6DvsIUDFaR7JxKTSMh/2';
try {
$conn = new PDO("mysql:host=" . $servername . ";dbname=e0912343_Fixtures", $DB_username, $DB_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$statement = $conn->prepare("SELECT * FROM Admin WHERE Username= :Username");
$result= $statement->execute(array(':Username'=>':Username'));
if ($result){
if(password_verify('User1', $stored_password)) {
echo "<script> alert('The ID or password entered is not valid. Please enter a valid username and password') </script>";
} else {
echo "Welcome to the Admin Page!";
}
$_SESSION['Name']= $Username;
header("location: Admin.php"); // redirect user to the Admin.php web page
}
}
catch(PDOException $e) {
echo "An error occured: " . $e->getMessage();
}
$conn = null;
}
?>
If so, your password checking is
if(password_verify('User1', $stored_password)) {
So $stored_password is the hashed password. But you are checking this against User1. As far as I can see you are not checking $Password which is the password entered by the user?
If that is the current code, the stored password is hard-coded, not being retrieved from the database. The query is executed, but there is no fetch() to get the results.
Hi everyone, I took stock of the mess I was getting myself into and decided to stop and go back to my old code. @spaceshiptrooper’s $_SERVER['REQUEST_METHOD] suggestion did get rid of the header issue and the message was alive and well but I couldn’t sign in with the user credentials no matter what I did. @droopsnoot comment made me think about it being hardcoded but I don’t think that’s the problem as well. However, maybe it was the length of the password? In my table and the CPanel, the allowed password length is 12 characters. Not sure if using hashed passwords and therefore making them longer, made the logging fail? In the end, my original code now works but all I did was to take the extra colon @wake689 said I had. I don’t know why it didn’t seem to work before and I gave up on it. Here’s it again just in case someone is curious. Thank you for all the help, I’m so pleased with all I’ve learnt in the past two days, I can’t thank you enough!
<?php
if (isset($_POST["Login"])) {
checkLogin($_POST["Name"], $_POST["Password"]);
}
function checkLogin($Username, $Password) {
$servername = "localhost";
$DB_username = "User1";
$DB_password = "password";
try {
$conn = new PDO("mysql:host=" . $servername . ";dbname=e0912343_Fixtures", $DB_username, $DB_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$statement = $conn->query("SELECT * FROM Admin WHERE Username='" . $Username ."' AND PASSWORD='" . $Password . "'");
$result = $statement->fetch();
if ($result == null) { // if Admin id and password doesn't match
echo "<script> alert('The ID or password entered is not valid. Please enter a valid username and password') </script>";
} else {
// start the session
session_start();
$_SESSION['Name']= $Username;
header("location: Admin.php"); // redirect Admin to the Admin.php web page
}
}
catch(PDOException $e) {
echo "An error occured: " . $e->getMessage();
}
$conn = null;
}
?>
<html lang="en">
<head>
<title>Login</title>
</head>
<body>
<header>
<table>
<tr>
<td></td>
<td><h1>Fixtures Maintenance</h1></td>
</table>
</header>
<section>
<h1>Login</h1>
<form name="Login" method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<table>
<tr>
<td>Username:</td>
<td><input type="text" name="Name"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="Password"></td>
</tr>
<tr>
<td colspan=2><input type="submit" name="Login" value="Login"></td>
</tr>
</table>
</form>
</section>
</body>
</html>
@droopsnoot thanks for the reminder. I think this will get a bit more complex as I advance in the course. As @wake689 pointed out, I can see that there is much more to the Login form that I am being exposed to right now!
I misspoke. It was the line break that you had in the middle of the javascript that caused it to not display the alert. But you have corrected that too.
The other change that you have made is that you no longer have session_start() in your login page - this should be at the top of the page that login directs you to after a successful login. Having it in your login page was stopping the header("location: Admin.php"); from working.
Just to reiterate what @droopsnoot says about plain text passwords.
There are other things you need to do to improve security too - don’t have this on a live Internet site in this state.
Are you able to use cPanel to alter the length of text allowed in the password column in your Admin table? I think you are getting close (-ish) to a working solution.
Thank you, too, for the feedback - it is frustrating when you put time and effort into helping folk and then you never hear from them again!
It is also worth remembering that if the OP is doing a course which leads to a test that needs to be passed, breaking out into code that hasn’t been taught as part of the course isn’t always a good thing. I know it should be, but it isn’t necessarily taken that way all the time. Few tutors will take the time to read up on the differences and concede that you might have a better way of doing things than their course taught you. Sometimes you have to just go with it, but remember the “proper” way to do things is very different, and that the course you are taking may not be as useful as you hoped.