phpsane Posted August 25, 2017 Share Posted August 25, 2017 Folks, Why does my login.php show nothing but a white empty page with nothing ? Error reporting is set in the config.php. Get no errors atall now! config.php <?php /* ERROR HANDLING */ declare(strict_types=1); ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // session start if(!session_start()) { session_start(); } // include files include 'conn.php'; include 'site_details.php'; // include functions include 'functions.php'; ?> site_details.php <?php $site_name = "myworld"; $social_network_name = "myworld"; $site_domain = "EDITED"; $site_admin_email = "myworld_admin@EDITED"; $social_network_admin_email = "myworld_admin@EDITED"; ?> functions.php <?php // functions file /* * check if user is logged by checking if session named "user" isset * return true if session "user" exists or false if not exists */ function is_logged() { if (isset($_SESSION["user"]) && !empty($_SESSION["user"])) { return true; } else { return false; } } ?> login.php <?php include 'config.php'; // check if user is already logged in if (is_logged() === true) { //Redirect user to homepage page after 5 seconds. header("refresh:5;url=home.php"); } if ($_SERVER['REQUEST_METHOD'] == "POST") { if (isset($_POST["login_username_or_email"]) && isset($_POST["login_password"])) { $username_or_email = trim(mysqli_real_escape_string($conn, $_POST["login_username_or_email"])); $password = $_POST["login_password"]; //Hashed Password. $hashed_password = password_hash($password, PASSWORD_DEFAULT); // Check if inputted Username is between 8 to 30 characters long or not. Or, if inputed Email is valid or not. if ((strlen($username_or_email) < 8 || strlen($username_or_email) > 30) || (!filter_var($username_or_email, FILTER_VALIDATE_EMAIL))) { $_SESSION['error'] = "Your Username or Email is incorrect! If you input your Username, then it must be between 8 to 30 characters long. If you input your Email, then it must be a valid one!"; exit; } // Check if Password is between 8 to 30 characters long or not. elseif (strlen($password) < 8 || strlen($password) > 30) { $_SESSION['error'] = "Password must be between 6 to 30 characters long!"; exit; } //Select Username and Email to check against Mysql DB if they are already registered or not. $stmt = mysqli_stmt_init($conn); if($stmt = mysqli_prepare($conn, "SELECT accounts_activations, usernames, emails, passwords FROM users WHERE passwords = ?")) { mysqli_stmt_bind_param($stmt, 's', $hashed_password); mysqli_stmt_execute($stmt); //$result = mysqli_stmt_get_result($stmt); //Use either this line, or ... $result = mysqli_stmt_bind_result($stmt, $db_account_activation_state, $db_username, $db_email, $db_password); // ... this line. But not both. $row = mysqli_fetch_array($result, MYSQLI_ASSOC); mysqli_stmt_close($stmt); // Check if inputted Username or Email is registered or not. //Either type following paragraph or the next one but not both. Ask in forum which one is best. /* PARAGRAPH 1 if (($username_or_email == $row['usernames'] || $username_or_email == $row['emails']) && $hashed_password == $row['passwords']) // either this paragraph or ... { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { $error = "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don;t find an email from us."; exit; } } */ //PARAGRAPH 2 if (($username_or_email == $db_username || $username_or_email == $db_email) && password_verify($hashed_password, $db_password)) // ..... this paragraph. But not both. { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { $error = "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don;t find an email from us."; exit; } } $_SESSION["user"] = $username; //If 'Remember Me' check box is checked then set the cookie. //if(!empty($_POST["login_remember"])) // Either use this line .... if (isset($_POST['login_remember']) && $_post['login_remember'] == "on") // ...or this line. But not both! { setcookie("login_username_or_email", $username_or_email, time()+ (10*365*24*60*60)); setcookie("login_password", $login_password, time()+ (10*365*24*60*60)); } else { //If Cookie is available then use it to auto log user into his/her account! if (isset($_COOKIE['login_username_or_email'])) { setcookie("login_username_or_email","",""); } if (isset($_COOKIE['login_password'])) { setcookie("login_password", "", ""); } } header("location:home.php"); } else { $_SESSION['error'] = "That Username or Email is not registered!"; exit; } } } ?> <!DOCTYPE html> <html> <head> <title><?php $site_name?> Member Login Page</title> <meta charset="utf-8"> </head> <body> <div class = "container"> <form method="post" action=""> <center><h3><?php $site_name ?> Member Login Form</h3></center> <div class="text-danger"> <?php if(isset($message)) { echo $message; } ?> <div class="form-group"> <center><label>Username/Email:</label> <input type="text" placeholder="Enter Username or Email" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center> </div> <div class="form-group"> <center><label>Password:</label> <input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center> </div> <div class="form-group"> <center><label>Remember Login Details:</label> <input type="checkbox" name="login_remember" /></center> </div> <div class="form-group"> <center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center> </div> <div class="form-group"> <center><font color="red" size="3"><b>Forgot your password ?</b><br><a href="login_password_reset.php">Reset it here!</a></font></center> <center><font color="red" size="3"><b>Not registered ?</b><br><a href="register.php">Register here!</a></font></center> </form> </div> </body> </html> Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 26, 2017 Share Posted August 26, 2017 So, what happened with your previous problem? Have you followed my recommendation and fixed it? Then you should go back, write a quick follow-up and mark the thread as solved. Several people have invested quite a lot of time to help you, so I think it's only fair if you give some feedback for future users. If you're still running around with the same issue you had two weeks ago, then I suggest you actually read the replies, especially the part about minimal examples. When you just post a big collection of broken scripts, most users will ignore you, because nobody has the time to debug your entire stuff for free. Contrary to popular belief, we do not have magic powers which would allow us to immediately “see” every bug. We have to actually read the code, just like you. Long story short: Take care of your old thread. Reduce the problem. It's generally a good idea to write code step by step and commit each working part. Then you at least have a vague idea of where the problem might be. Fix your error reporting. Enable it in your php.ini, not at runtime. When you change the configuration at runtime, you're going to miss all problems which happen before the code is executed (syntax problems etc.). Quote Link to comment Share on other sites More sharing options...
phpsane Posted August 26, 2017 Author Share Posted August 26, 2017 (edited) Jacques1, My previous problem has been solved by me. https://forums.phpfreaks.com/topic/304592-warning-mysqli-stmt-execute-expects-parameter-1-to-be-mysqli-stmt-boolean-given-in-on-line-42/?view=getnewpost But, you are welcome to make your final comment there. And then I can close the thread there as "solved". But we still got to solve this thread's issue, though. Tonight, I got rid of the "exits" and "$_SESSION['error'] =" but still no luck. I still get the white empty page! Here's the update: <?php include 'config.php'; // check if user is already logged inif (is_logged() === true) {//Redirect user to homepage page after 5 seconds.header("refresh:5;url=home.php");} if ($_SERVER['REQUEST_METHOD'] == "POST"){if (isset($_POST["login_username_or_email"]) && isset($_POST["login_password"])){$username_or_email = trim(mysqli_real_escape_string($conn, $_POST["login_username_or_email"]));$password = $_POST["login_password"]; //Hashed Password.$hashed_password = password_hash($password, PASSWORD_DEFAULT); // Check if inputted Username is between 8 to 30 characters long or not. Or, if inputed Email is valid or not.if ((strlen($username_or_email) < 8 || strlen($username_or_email) > 30) || (!filter_var($username_or_email, FILTER_VALIDATE_EMAIL))){echo "Your Username or Email is incorrect! If you input your Username, then it must be between 8 to 30 characters long.If you input your Email, then it must be a valid one!"; }// Check if Password is between 8 to 30 characters long or not.elseif (strlen($password) < 8 || strlen($password) > 30) {echo "Password must be between 6 to 30 characters long!"; } //Select Username and Email to check against Mysql DB if they are already registered or not.$stmt = mysqli_stmt_init($conn);if($stmt = mysqli_prepare($conn, "SELECT accounts_activations, usernames, emails, passwords FROM users WHERE passwords = ?")){mysqli_stmt_bind_param($stmt, 's', $hashed_password);mysqli_stmt_execute($stmt);//$result = mysqli_stmt_get_result($stmt); //Use either this line, or ...$result = mysqli_stmt_bind_result($stmt, $db_account_activation_state, $db_username, $db_email, $db_password); // ... this line. But not both. $row = mysqli_fetch_array($result, MYSQLI_ASSOC);mysqli_stmt_close($stmt); // Check if inputted Username or Email is registered or not.//Either type following paragraph or the next one but not both. Ask in forum which one is best./* PARAGRAPH 1if (($username_or_email == $row['usernames'] || $username_or_email == $row['emails']) && $hashed_password == $row['passwords']) // either this paragraph or ...{echo "IF Triggered";}else{if($row['accounts_activations'] == '0'){echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don;t find an email from us.";exit;}} */ //PARAGRAPH 2if (($username_or_email == $db_username || $username_or_email == $db_email) && password_verify($hashed_password, $db_password)) // ..... this paragraph. But not both.{echo "IF Triggered";}else{if($row['accounts_activations'] == '0'){echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don;t find an email from us."; }} $_SESSION["user"] = $username; //If 'Remember Me' check box is checked then set the cookie. //if(!empty($_POST["login_remember"])) // Either use this line ....if (isset($_POST['login_remember']) && $_post['login_remember'] == "on") // ...or this line. But not both!{setcookie("login_username_or_email", $username_or_email, time()+ (10*365*24*60*60));setcookie("login_password", $login_password, time()+ (10*365*24*60*60));}else{//If Cookie is available then use it to auto log user into his/her account!if (isset($_COOKIE['login_username_or_email'])){setcookie("login_username_or_email","","");}if (isset($_COOKIE['login_password'])){setcookie("login_password", "", "");}}header("location:home.php?user=$username");}else{echo "That Username or Email is not registered!"; }}} ?> <!DOCTYPE html><html><head><title><?php $site_name?> Member Login Page</title> <meta charset="utf-8"></head><body><div class = "container"><form method="post" action=""><center><h3><?php $site_name ?> Member Login Form</h3></center><div class="text-danger"><?phpif(isset($message)){ echo $message;}?><div class="form-group"><center><label>Username/Email:</label><input type="text" placeholder="Enter Username or Email" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center></div><div class="form-group"><center><label>Password:</label><input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center></div><div class="form-group"><center><label>Remember Login Details:</label><input type="checkbox" name="login_remember" /></center></div><div class="form-group"><center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center></div><div class="form-group"><center><font color="red" size="3"><b>Forgot your password ?</b><br><a href="login_password_reset.php">Reset it here!</a></font></center><center><font color="red" size="3"><b>Not registered ?</b><br><a href="register.php">Register here!</a></font></center></form></div></body></html> Edited August 26, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
phpsane Posted August 26, 2017 Author Share Posted August 26, 2017 (edited) Here is my most latest login.php. I don't understand why, when you click the "Login" button, it reloads the same login page. Thus going in a loop giving no other responses. Apart from the echo: The ELSE of isset Login button getting triggered !End of script reached! You will find this ELSE in the script flow, just above the html form. When you click the "Login" button, the IF->THEN; should trigger on the ISSET. But it is not. Instead, the ELSE is! That is the mystery! login.php Look at line 13: if (!$_SERVER['REQUEST_METHOD'] == "POST") Line 108 - 114: else { echo "The ELSE of isset Login button getting triggered !"; } echo "End of script reached!"; ?> <?php include 'config.php'; // check if user is already logged in if (is_logged() === true) { //Redirect user to homepage page after 5 seconds. header("refresh:5;url=home.php?user=$username"); } if (!$_SERVER['REQUEST_METHOD'] == "POST") { if (isset($_POST["login_username"]) && isset($_POST["login_password"])) { $username = trim(mysqli_real_escape_string($conn, $_POST["login_username"])); $password = $_POST["login_password"]; // Check if inputted Username is between 8 to 30 characters long or not. Or, if inputed Email is valid or not. /*if ((strlen($username) < 8 || strlen($username) > 30) || (!filter_var($username, FILTER_VALIDATE_EMAIL))) { echo "Your Username is incorrect! If you input your Username, then it must be between 8 to 30 characters long.; } // Check if Password is between 8 to 30 characters long or not. elseif (strlen($password) < 8 || strlen($password) > 30) { echo "Password must be between 6 to 30 characters long!"; } */ //Select Username and Email to check against Mysql DB if they are already registered or not. $stmt = mysqli_stmt_init($conn); if($stmt = mysqli_prepare($conn, "SELECT accounts_activations, usernames, emails, passwords FROM users WHERE usernames = ?")) { mysqli_stmt_bind_param($stmt, 's', $username); mysqli_stmt_execute($stmt); //$result = mysqli_stmt_get_result($stmt); //Use either this line, or ... $result = mysqli_stmt_bind_result($stmt, $db_account_activation_state, $db_username, $db_email, $db_password); // ... this line. But not both. $row = mysqli_fetch_array($result, MYSQLI_ASSOC); // Check if inputted Username or Email is registered or not. //Either type following paragraph or the next one but not both. Ask in forum which one is best. /* PARAGRAPH 1 if (($username == $row['usernames'] && $password == $row['passwords']) // either this paragraph or ... { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don't find an email from us."; exit; } } */ //PARAGRAPH 2 if ($username_or_email == $db_username && password_verify($password, $db_password)) // ..... this paragraph. But not both. { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don't find an email from us."; } } $_SESSION["user"] = $username; //If 'Remember Me' check box is checked then set the cookie. if(!empty($_POST["login_remember"])) // Either use this line .... //if (isset($_POST['login_remember']) && $_post['login_remember'] == "on") // ...or this line. But not both! { setcookie("login_username_or_email", $username, time()+ (10*365*24*60*60)); setcookie("login_password", $login_password, time()+ (10*365*24*60*60)); } else { //If Cookie is available then use it to auto log user into his/her account! if (isset($_COOKIE['login_username'])) { setcookie("login_username","",""); } if (isset($_COOKIE['login_password'])) { setcookie("login_password", "", ""); } } header("location:home.php?user=$username"); } else { echo "That Username or Email is not registered!"; } } else { echo "else of isset getting triggered !"; } } else { echo "The ELSE of isset Login button getting triggered !"; } echo "End of script reached!"; ?> <!DOCTYPE html> <html> <head> <title><?php $site_name?> Member Login Page</title> <meta charset="utf-8"> </head> <body> <div class = "container"> <form method="post" action=""> <center><h3><?php $site_name ?> Member Login Form</h3></center> <div class="text-danger"> <?php if(isset($message)) { echo $message; } ?> <div class="form-group"> <center><label>Username/Email:</label> <input type="text" placeholder="Enter Username or Email" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center> </div> <div class="form-group"> <center><label>Password:</label> <input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center> </div> <div class="form-group"> <center><label>Remember Login Details:</label> <input type="checkbox" name="login_remember" /></center> </div> <div class="form-group"> <center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center> </div> <div class="form-group"> <center><font color="red" size="3"><b>Forgot your password ?</b><br><a href="login_password_reset.php">Reset it here!</a></font></center> <center><font color="red" size="3"><b>Not registered ?</b><br><a href="register.php">Register here!</a></font></center> </form> </div> </body> </html> Edited August 26, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted August 26, 2017 Share Posted August 26, 2017 What is the exclamation mark doing there: if (!$_SERVER['REQUEST_METHOD'] == "POST") ^^^ 1 Quote Link to comment Share on other sites More sharing options...
phpsane Posted August 26, 2017 Author Share Posted August 26, 2017 (edited) What is the exclamation mark doing there: if (!$_SERVER['REQUEST_METHOD'] == "POST") ^^^ Without the exclamation mark, it should trigger the IF->THEN; to trigger the script. If clicked "Login" button THEN run the script. if ($_SERVER['REQUEST_METHOD'] == "POST") But, the ELSE was wrongfully getting triggered. And so, I thought, I'll switch the IF to IF->Not; That might trigger the IF->THEN. Hence, the exclamation mark to represent the "Not". But no luck. Even no luck with the following: if ($_SERVER['REQUEST_METHOD'] != "POST") if ($_SERVER['REQUEST_METHOD'] !== "POST") if (!isset($_POST["login_username"]) && !isset($_POST["login_password"])) Note, the exclamation marks again. Yes, yes. I know. I am now trying invalid coding. But, you can't blame me for experimenting. Again, the ELSE gets triggered. Infact, for some reason the script seems to be hell bent towards triggering the ELSE. A mystery now (to me, atleast). Try without the exclamation marks on your wamp/xampp and you will see that, the ELSE still gets triggered no matter what. What do you suspect is wrong ? Thanks! if ($_SERVER['REQUEST_METHOD'] != "POST") Edited August 26, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
phpsane Posted August 26, 2017 Author Share Posted August 26, 2017 (edited) Issue solved as of now. My html form's input item's names had typos. Were not matching with the names that the php script was searching for. Error <div class="form-group"> <center><label>Username/Email:</label> <input type="text" placeholder="Enter Username" name="login_username_or_email" value="<?php if(isset($_COOKIE["login_username_or_email"])) echo $_COOKIE["login_username_or_email"]; ?>"</center> </div> Fix: <div class="form-group"> <center><label>Username/Email:</label> <input type="text" placeholder="Enter Username" name="login_username" value="<?php if(isset($_COOKIE["login_username"])) echo $_COOKIE["login_username"]; ?>"</center> </div> Edited August 26, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
phpsane Posted August 26, 2017 Author Share Posted August 26, 2017 (edited) Php Experts! Can anyone figure-out why the following script logs anyone in, even if you mis-typed your username ? I logged-out and deleted the cookie. Then, tried re-logging in with a typo in Username. And it logged me in when it should not. Where am I making the mistake in my coding ? <?php include 'config.php'; // check if user is already logged in if (is_logged() === true) { //Redirect user to homepage page after 5 seconds. header("refresh:2;url=home.php"); } if ($_SERVER['REQUEST_METHOD'] == "POST") { if (isset($_POST["login_username"]) && isset($_POST["login_password"])) { $username = trim(mysqli_real_escape_string($conn, $_POST["login_username"])); $password = $_POST["login_password"]; // Check if inputted Username is between 8 to 30 characters long or not. Or, if inputed Email is valid or not. if ((strlen($username) < 8 || strlen($username) > 30) || (!filter_var($username, FILTER_VALIDATE_EMAIL))) { echo "Your Username is incorrect! If you input your Username, then it must be between 8 to 30 characters long."; } // Check if Password is between 8 to 30 characters long or not. elseif (strlen($password) < 8 || strlen($password) > 30) { echo "Password must be between 6 to 30 characters long!"; } //Select Username and Email to check against Mysql DB if they are already registered or not. $stmt = mysqli_stmt_init($conn); if($stmt = mysqli_prepare($conn, "SELECT accounts_activations, usernames, emails, passwords FROM users WHERE usernames = ?")) { mysqli_stmt_bind_param($stmt, 's', $username); mysqli_stmt_execute($stmt); $result = mysqli_stmt_bind_result($stmt, $db_account_activation_state, $db_username, $db_email, $db_password); // ... this line. But not both. $row = mysqli_fetch_array($result, MYSQLI_ASSOC); if ($username == $db_username && password_verify($password, $db_password)) // ..... this paragraph. But not both. { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don't find an email from us."; } } $_SESSION["user"] = $username; //If 'Remember Me' check box is checked then set the cookie. if(!empty($_POST["login_remember"])) { setcookie("login_username", $username, time()+ (10*365*24*60*60)); setcookie("login_password", $password, time()+ (10*365*24*60*60)); } else { //If Cookie is available then use it to auto log user into his/her account! if (isset($_COOKIE['login_username'])) { setcookie("username","",""); } if (isset($_COOKIE['login_password'])) { setcookie("login_password", "", ""); } } header("location:home.php?user=$username"); } else { echo "That Username or Email is not registered!"; } } else { echo "Else of isset is getting triggered !"; } } else { echo "The ELSE of isset Login button getting triggered !"; } echo "End of script reached!"; ?> <!DOCTYPE html> <html> <head> <title><?php $site_name?> Member Login Page</title> <meta charset="utf-8"> </head> <body> <div class = "container"> <form method="post" action=""> <center><h3><?php $site_name ?> Member Login Form</h3></center> <div class="text-danger"> <?php if(isset($message)) { echo $message; } ?> <div class="form-group"> <center><label>Username/Email:</label> <input type="text" placeholder="Enter Username" name="login_username" value="<?php if(isset($_COOKIE["login_username"])) echo $_COOKIE["login_username"]; ?>"</center> </div> <div class="form-group"> <center><label>Password:</label> <input type="password" placeholder="Enter password" name="login_password" value="<?php if(isset($_COOKIE["login_password"])) echo $_COOKIE["login_password"]; ?>"></center> </div> <div class="form-group"> <center><label>Remember Login Details:</label> <input type="checkbox" name="login_remember" /></center> </div> <div class="form-group"> <center><input type="submit" name="login_submit" value="Login" class="button button-success" /></center> </div> <div class="form-group"> <center><font color="red" size="3"><b>Forgot your password ?</b><br><a href="login_password_reset.php">Reset it here!</a></font></center> <center><font color="red" size="3"><b>Not registered ?</b><br><a href="register.php">Register here!</a></font></center> </form> </div> </body> </html> Edited August 26, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted August 27, 2017 Share Posted August 27, 2017 (edited) back one problem, this is the reason that you DON'T put isset() tests around every form field. after you have detected that the form has been submitted (the $_SERVER['REQUEST_METHOD'] test) all form fields, except for unchecked checkboxes and unchecked radio buttons, will be set. by using isset() for form fields that WILL be set, if you have a valid form with those fields in them, you are hiding problems and just cluttering up your code with unnecessary typing. --- as to your current problem, sorry for how this sounds, but there is almost nothing about that code that is worth saving. it is even doing some database things that don't go together and are probably producing php error messages. here's a list, which is likely missing some of the problems, because there are just too many - 1) stop testing if boolean values are equal or not equal to true/false values. 2) if the current user is logged in, when you do a redirect to some other page, you must stop program execution, by having an exit; in your code. without an exit;, all the code on your page still runs. 3) don't use isset() around form fields that WILL be set. 4) don't use mysqli_real_escape_string() on a value before you have validated it and since you are using a prepared query, don't use mysqli_real_escape_string() at all. it changes the value and will cause your validation to operate on a different value than what was submitted and with a prepared query, you don't need to escape the data. 5) you should store validation error messages in a php array variable. this will let you setup separate and unique validation errors, except when logging someone in, you should not identify if it is the username/email or password that was wrong. for a login script, just output a generic message that the login failed. 6) for your login process, all you care about for validation is that the trimmed form data is not empty. you don't care about lengths (when registering a user, you would care about the lengths.) 7) don't use mysqli_stmt_init(), which you are using incorrectly anyways. if it hasn't already been mentioned, switch to use the php PDO extension. it is much easier to use than the php mysqli extension. this will avoid all the lines of code using - mysqli_stmt_init(), mysqli_stmt_bind_param(), mysqli_stmt_bind_result(). 9) you cannot directly use mysqli_fetch_array() with a prepared query and you should be getting a php error at this statement. if you switch to the PDO extension, you CAN use any of its fetch statements, regardless of how you execute the query. 10) if the user hasn't activated the account, you must test for and handle this condition first. 11) if the query matches a row, you know that the username matched. there's no good reason to re-test the username in php logic. 12) only if the query matched a row, the user has activated the account, and password_verify() confirms that the entered password matches the stored hash, should you store a value in the session variable and the value you store in the session variable should be the user's id (auto-increment column value), not the username. it appears to me that your code is unconditionally assigning the $username variable to the session variable, resulting in it being set even if the necessary conditions have not been met. while some of the indentation in your code may have been lost due to the forum's operation, it would help if you correctly indented your code, so that you can see where the statements are actually located in the logic. 13) i'm pretty sure i am repeating at this point, but do NOT store the username/password in cookies and do NOT populate any form fields with these cookie values. if you want a 'remember me' feature, at the point where the user has successfully logged in, generate a unique random token, store this in a cookie and store it in a column in your users table. if the visitor returns to your site and the login session variable doesn't exist and the cookie does, use the token value from the cookie to query for the user's id. if found, store the user's id in the session variable, the same as if they had just logged in via a username/password. what you would populate the form field values with are any submitted data values, when there are validation errors, so that the visitor doesn't need to keep tying in values. 14) you are also echoing things before the start of your html document. if you store the validation and login error messages in an array as has been suggested, you can test and output the contents of that array in an appropriate place inside your html document. Edited August 27, 2017 by mac_gyver 1 Quote Link to comment Share on other sites More sharing options...
phpsane Posted August 27, 2017 Author Share Posted August 27, 2017 @mac_guyver, Thank you very much for your in-depth explanation. Most appreciated by me. Also, your feed-back would be most helpful and appreciated by newbies who visit this thread in the future. If you don't mind, do you mind capitalizing the first letters of every one of your sentences (like I am doing) ? I am used to reading things that way. I am going to use your feed-back as a guide from now and refer myself back to it from time to time when trying to fix my script. And, when I return back to it to jog my memory (when I forget things you have already covered here). As you know, reading a lengthy feed-back once does not sink all the suggestions into your head in one go. I will have to read and re-read over and over again a few times, a few days in a row and practice based upon it. That way, everything will slowly sink into my brain. Will get memorized. I will be able to slowly familiarize myself with your suggestions and that should prevent me from forgetting the basics you have suggested. Also, you and others will get saved from having to repeat yourselves the same things over and over again. I think it will take 2-3 days for me to fix my script and make it perfect. I will have to research on a lot of things you have suggested. Not familiar with every method you suggested. Will have to experiment a lot too. Hence, the delay it would take to fix it. In the meanwhile, I am opening another thread on another issue and I hope to see you there. Thank You! Quote Link to comment Share on other sites More sharing options...
phpsane Posted September 9, 2017 Author Share Posted September 9, 2017 (edited) Mac_Guyver, I am now trying to fix my script based upon your suggestions. It's nearly a fortnight and I was supposed to fix this in 2-3 days. Anyways. I have some questions/ I did not understand some of your suggestions. ISSUE 1 >>back one problem, this is the reason that you DON'T put isset() tests around every form field.<< Q1. What do you mean ? I thought every script tests every form using the isset function. Whether the form fields have been set or not. ISSUE 2 >> after you have detected that the form has been submitted (the $_SERVER['REQUEST_METHOD'] test) all form fields, except for unchecked checkboxes and unchecked radio buttons, will be set. by using isset() for form fields that WILL be set, if you have a valid form with those fields in them, you are hiding problems and just cluttering up your code with unnecessary typing.<< Q2. Sorry. I did not understand this. Can you elaborate a bit more ? ISSUE 3 >>1) stop testing if boolean values are equal or not equal to true/false values.<< Then how am I supposed to check if the Username or Password the user has inputted, during login, is accurate or false ? How do you want me to code it ? Care to show a sample ? ISSUE 4 2) if the current user is logged in, when you do a redirect to some other page, you must stop program execution, by having an exit; in your code. without an exit;, all the code on your page still runs. I have fixed that. Thanks! ISSUE 5 3) don't use isset() around form fields that WILL be set. What exactly do you mean here ? Do you mean to say that, at one point of the script flow, if the form field has not been set then at that point I should not be checking if it has been set or not ? If that is what you mean then care to point-out where I did this so I can fix it ? As of now, I can;t see where I did this. ISSUE 6 4) don't use mysqli_real_escape_string() on a value before you have validated it and since you are using a prepared query, don't use mysqli_real_escape_string() at all. it changes the value and will cause your validation to operate on a different value than what was submitted and with a prepared query, you don't need to escape the data. In other words, mysqli_real_escape_string is an old timer which was used before the prepared statements and it was not useful enough to stop sql injection and so the prepared statements was invented. And, I should not be using both methods but one and the prepared statements is best. Ok, I have fixed this. ISSUE 7 >>5) you should store validation error messages in a php array variable. this will let you setup separate and unique validation errors, except when logging someone in, you should not identify if it is the username/email or password that was wrong. for a login script, just output a generic message that the login failed.<< In other words, my error message should not reveal which part of the login failed. Username or Password. Otherwise, hackers would spend their time concentrating on the one they got wrong. And that would make their lives easier. I was advised in the past like you advised. But I forgot to act upon it. Thanks for reminding me. I have acted upon it now. But, it would be better if you show an example of how the error message should be. I mean should I use session error or just echo or anything else ? I prefer a sample code. Anybody are welcome to reply to this post as I fear Mac_Guyver will not be around to answer it. You have my questions numbered for your convenience to answer in likewise manner. Thank You! Edited September 9, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
phpsane Posted September 9, 2017 Author Share Posted September 9, 2017 Mac_Guyver, ISSUE 8 >>6) for your login process, all you care about for validation is that the trimmed form data is not empty. you don't care about lengths (when registering a user, you would care about the lengths.)<< I believe you don't like this: if ((strlen($username) < 8 || strlen($username) > 30) || (!filter_var($username, FILTER_VALIDATE_EMAIL))) { echo "Your Username is incorrect! If you input your Username, then it must be between 8 to 30 characters long."; } // Check if Password is between 8 to 30 characters long or not. elseif (strlen($password) < 8 || strlen($password) > 30) { echo "Password must be between 6 to 30 characters long!"; } You are right. I should only mention the requirements of the Username & Password during registration. And not during login. And so, I have erased those lines. (I actually grabbed them from the registration.php). I never should have. I never did on the other version (the version that does not have sql injection prevention). On the other version, the code went like this: if ($login_username_or_email == $db_username && $login_password == $db_password || $login_username_or_email == $db_email && $login_password == $db_password) Here, the user is given a choice to either input his Username or his Email. Therefore, the script checks if either is submitted and checks the db for the one that is submitted. On the sql prevention version, I originally coded like the following where both the Username or Email is checked but then I thought writing code to check for both using the Prepared Statements will be too confusing for me in the beginning since I'm still learning the Prepared Statements. And so, cut it down to just checking for the Username (like in the code you see that follows later). Check Username/Password if($stmt = mysqli_prepare($conn, "SELECT accounts_activations, usernames, emails, passwords FROM users WHERE usernames = ? OR emails = ?")) { mysqli_stmt_bind_param($stmt, 'ss', $username, $email); mysqli_stmt_execute($stmt); //$result = mysqli_stmt_get_result($stmt); //Use either this line, or ... $result = mysqli_stmt_bind_result($stmt, $db_account_activation_state, $db_username, $db_email, $db_password); // ... this line. But not both. $row = mysqli_fetch_array($result, MYSQLI_ASSOC); // Check if inputted Username or Email is registered or not. //Either type following paragraph or the next one but not both. Ask in forum which one is best. /* PARAGRAPH 1 if (($username_or_email == $row['usernames'] || $username_or_email == $row['emails']) && $password == $row['passwords']) // either this paragraph or ... { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don't find an email from us."; exit; } } */ //PARAGRAPH 2 if (($username_or_email == $db_username || $username_or_email == $db_email) && password_verify($password, $db_password)) // ..... this paragraph. But not both. { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don't find an email from us."; } } Check Username only if($stmt = mysqli_prepare($conn, "SELECT accounts_activations, usernames, emails, passwords FROM users WHERE usernames = ?")) { mysqli_stmt_bind_param($stmt, 's', $username); mysqli_stmt_execute($stmt); //$result = mysqli_stmt_get_result($stmt); //Use either this line, or ... $result = mysqli_stmt_bind_result($stmt, $db_account_activation_state, $db_username, $db_email, $db_password); // ... this line. But not both. $row = mysqli_fetch_array($result, MYSQLI_ASSOC); // Check if inputted Username or Email is registered or not. //Either type following paragraph or the next one but not both. Ask in forum which one is best. /* PARAGRAPH 1 if (($username == $row['usernames'] && $password == $row['passwords']) // either this paragraph or ... { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don't find an email from us."; exit; } } */ //PARAGRAPH 2 if ($username == $db_username && password_verify($password, $db_password)) // ..... this paragraph. But not both. { echo "IF Triggered"; } else { if($row['accounts_activations'] == '0') { echo "You have not activated your account yet! Check your email for instructions on how to activate it. Check your spam folder if you don't find an email from us."; } } ISSUE 9 >>7) don't use mysqli_stmt_init(), which you are using incorrectly anyways. if it hasn't already been mentioned, switch to use the php PDO extension. it is much easier to use than the php mysqli extension. this will avoid all the lines of code using - mysqli_stmt_init(), mysqli_stmt_bind_param(), mysqli_stmt_bind_result().<< You mean I should not use ? But without it, I was getting error. $stmt = mysqli_stmt_init($conn); Anyway, how to use it ? A code sample would be appreciated. A sample of the full context. As for PDO, if you can show an example of this concerned context in pdo then that too would be most appreciated it. ISSUE 10 >>9) you cannot directly use mysqli_fetch_array() with a prepared query and you should be getting a php error at this statement. if you switch to the PDO extension, you CAN use any of its fetch statements, regardless of how you execute the query.<< Ok. I understand, But since I've come this far with mysqli then let's complete this first. How-about you show me a sample how it should have been without the mysqli_fetch ? A sample of the full context. ISSUE 11 >>10) if the user hasn't activated the account, you must test for and handle this condition first.<< How so ? What is wrong with my method & steps ? During login: 1. Checks if the username/email & password is correct or not. 2. Then it checks whether the account has been activated or not by the user by verifying the user's email. How-about a pseudo code of how it should have been ? ISSUE 12 >>11) if the query matches a row, you know that the username matched. there's no good reason to re-test the username in php logic.<< You ,mean, since I already have the following: if($stmt = mysqli_prepare($conn, "SELECT accounts_activations, usernames, emails, passwords FROM users WHERE usernames = ?")) { Then no need to use either the following: /* PARAGRAPH 1 if (($username == $row['usernames'] && $password == $row['passwords']) // either this paragraph or ... //PARAGRAPH 2 if ($username == $db_username && password_verify($password, $db_password)) // ..... this paragraph. But not both. Ok. I understand. But out of the 3 samples mentioned above, which one is best to keep ? I will deal with the final 3 issues in another post. @Anybody: Anybody are welcome to reply to this post as I fear Mac_Guyver won't really be around to answer it. Quote Link to comment Share on other sites More sharing options...
phpsane Posted September 9, 2017 Author Share Posted September 9, 2017 (edited) Mac_Guyver, ISSUE 13 >> 12) only if the query matched a row, the user has activated the account, and password_verify() confirms that the entered password matches the stored hash, should you store a value in the session variable and the value you store in the session variable should be the user's id (auto-increment column value), not the username.<< In other words, you are saying that, if the Username & Password combination exists then it's obvious the user has activated his account and if they don't exist then they have not. And so, there is no need for the column in my mysql tbl "account_activation_status" and no need for the login.php script to check this column for "1" (where "1" is activated" and "0" inactive/pending activation). Anyway, let me explain why I did it this way and then you can conclude whether I should still do it the way I have or not. When the user registers via registration.php, the "account_activation_status" column is set to "0". Only when the user checks his email and clicks the account activation link then his email is taken into account as verified and this column switches to "1". Else, it stays "0". Now during login, if the Username & Password matches then the script checks if the column has been set to "1" or not. If not, then that means the user's email has not been verified (he has not clicked the emailed link) and his account has not been activated. And so, he gets an alert to click the link in his email to verify his email and activate his account. Simple method really to verify the user's email. I will leave this part as it is unless you or some other pro say to do otherwise. ISSUE 14 >>it appears to me that your code is unconditionally assigning the $username variable to the session variable, resulting in it being set even if the necessary conditions have not been met. while some of the indentation in your code may have been lost due to the forum's operation, it would help if you correctly indented your code, so that you can see where the statements are actually located in the logic.<< Thanks for bringing this to my attention! I should have added the "exit" on the conditions so the script flows no further if the conditions are not met (Username and/or Password don't match) and the user session is not set. Fixed this. ISSUE 15 >>13) i'm pretty sure i am repeating at this point, but do NOT store the username/password in cookies and do NOT populate any form fields with these cookie values. if you want a 'remember me' feature, at the point where the user has successfully logged in, generate a unique random token, store this in a cookie and store it in a column in your users table. if the visitor returns to your site and the login session variable doesn't exist and the cookie does, use the token value from the cookie to query for the user's id. if found, store the user's id in the session variable, the same as if they had just logged in via a username/password. what you would populate the form field values with are any submitted data values, when there are validation errors, so that the visitor doesn't need to keep tying in values.<< I understand. I actually copied the cookies section from somewhere and the originator of the code stored the password in the cookie. I was advised by another as you are advising but I forgot to fix it. Thanks for reminding me and no you have not repeated this. I understand that it is better to use the cookie to save user's inputs in his hdd (where cookies are saved) and get the cookie to type those inputs when the user sees error and the inputs are deleted. That way, user does not need to retype the form fields. Now, about saving a token in the user's hdd instead of password for the login's "Remember Me" feature. Everyone advises not to save password in the cookie section in the user's hdd because other softwares such as malwares and spywares might steal the password. But, if I save a token instead in the user's hdd in the cookie section then cannot these same spywares and malwares steal the token and use it to login to the user's account ? What am I missing here ? ISSUE 16 >>14) you are also echoing things before the start of your html document. if you store the validation and login error messages in an array as has been suggested, you can test and output the contents of that array in an appropriate place inside your html document.<< These echos are triggered by the php conditions (when user types in incorrect login details) and so they won't trigger at the beginning of the script before the html form is encountered. I don't see these echos any different than the validation and login errors you are suggesting since all these error types are getting triggered by php conditions. Actually, what are the real differences and benefits of the validation and login error messages over the standard echoing of error messages ? I am failing to understand the whole point here. I am sure other newbies require more elaboration here too. Thanks in advance for your future replies to my 3 posts. @Anybody. Anybody are welcome to reply to this post as I fear Mac_Guyver won't really be around to answer it. Edited September 9, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted September 10, 2017 Share Posted September 10, 2017 so, have you set up your development environment with php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini, since putting the setting in your code won't help with php syntax errors, so that php will help you by reporting and displaying all the errors it detects. then, have you started over, designing, writing, and testing your code, one small functional piece at a time, since there are too many problems in the current code to waste the time trying to fix it. no one here is going to spoon-feed you all the basic information you have skipped learning. we are here to help with actual programming problems. if you need help learning the basic information that is a prerequisite to writing your own code that actually works, you need to take a programming class, hire a tutor, or work through and internalize the information in some beginner php online tutorials. if you are not at the point of understanding the terminology being used, you are not at the point of even asking questions, because you won't understand the answers. the wording/terminology used in any particular subject is not to exclude people, but to prevent needing to write out books worth of information when explaining each concept. this is why books have been written, to cover the basics. you need to go and do some book learning and some experimenting on your own so that you get up to speed with the subject you are trying to participate in. Quote Link to comment Share on other sites More sharing options...
phpsane Posted September 10, 2017 Author Share Posted September 10, 2017 (edited) so, have you set up your development environment with php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini, since putting the setting in your code won't help with php syntax errors, so that php will help you by reporting and displaying all the errors it detects. then, have you started over, designing, writing, and testing your code, one small functional piece at a time, since there are too many problems in the current code to waste the time trying to fix it. no one here is going to spoon-feed you all the basic information you have skipped learning. we are here to help with actual programming problems. if you need help learning the basic information that is a prerequisite to writing your own code that actually works, you need to take a programming class, hire a tutor, or work through and internalize the information in some beginner php online tutorials. if you are not at the point of understanding the terminology being used, you are not at the point of even asking questions, because you won't understand the answers. the wording/terminology used in any particular subject is not to exclude people, but to prevent needing to write out books worth of information when explaining each concept. this is why books have been written, to cover the basics. you need to go and do some book learning and some experimenting on your own so that you get up to speed with the subject you are trying to participate in. Mac Thanks for bringing to my attention about the error reporting. I just noticed I did not have them even though I have them in all my other projects. Just copied them over and tested now. About that later. Dont worry, I understand the terminologies. The 3 previous posts I made were a direct response to your post and feedback on my script. I tell you what, I'm just providing below my scripts. That will give you an idea of how much I know or have learnt on php. These pages belong to my member registration/login script. It only has 3 pages: registration.php account_activation.php login.php home.php I am still working on. Now, about these 4 pages. The old version is working. Old version means the one that does not have prepared statements or sql prevention method. The new version is the one that has the sql prevention method. Anyway, I managed to add the sql prevention method on the registration.php, account_activation.php and login.php with the help of others. With your help, I am now managing to fix the problems (bad coding). Remember, the 3 previous posts I made were a direct response to your post and feedback on my script. Your feedback raised some questions. Hence I asked them in my previous 3 posts. Anyone are welcome to address them. The sooner I get them answered then the sooner I finish this project. I tested the 3 files. First 2 are working but the login.php is not working and I can't figureout what is wrong. I am mentioning the problem in another post. Thanks for your help and MOSTLY your INTENTION to help. PS - I know psychology. (I will try building a script that shows a 3d avatar that interacts with users. Some kind of an android. An AI built with php. Would be built based on psychology). You want to help but you are worried that I might not understand the terminologies you use and will ask too many questions. Your fears are unfounded. Test me. Try addressing the 3 posts and see whether I understand your terminologies or not. If I don't understand any, I can always check the manual or google. I watch youtube tutorial clips you know. Downloaded over a hundred from building member registration & login system, social networks (friend system, follow/unfollow system), building your own searchengine & web crawler etc. all on mysqli. A few built by pdo. How to create db, create tbl, delete tbl, edit tbl in mysql with php. So, don't worry. I have enough video tutorials to gain work experience. I usually play & pause vids and copy the codes by typing (no copy & paste). That is one form of code writing practice for me to memorize the codes. I only venture the forums when the codes show error. I tell you what, if you have any doubts whether I understand my code or not then ask me to explain any line and I will explain it. Infact, even though I copy the codes from youtube tutorials, I add the comments on my own as the tutorials don't provide comments. That should tell you how much I have learnt so far or how much I understand on php. So, it's not just about me copy & pasting and not understanding what I am copy & pasting. If I ever don't understand a code, I just ask in the forums. Now, I only prowl this forum. No other. Requinix, the Admin, keeps me company as I get most of my answers from him. Else, I would have left this forum by now to another where mass number of programmers prowl. Thanks for your concerns about my learning, though! I read through tizag.com php tutorial once more than a yr ago. Now revising on that and also from tutorialspoint.com, tutorialrepublic.com, codeacademy.com. After these, will start on phpdelusions.com and so don't worry about my tutorials. As of now, I need to figureout why my login.php is having problems. Fix that and my 1st php script/project is complete. Then, I will resume my other projects where I try adding a filter (banned words) on php-proxy. And another project where I try building my own web proxy with cURL. Soon, I will start a project to build my own searchengine & web crawler. And, I am still a beginner revising the basics of php. Have not even touched the pdo yet and so still not an intermediate coder. Is it not a wonder that I took on the task to build my own member reg/login site, web proxy and now trying to build my own web crawler & searchengine ? I will try building a forum too. Have a hunch how to do that. Anyway, don't forget to answer my 3 posts when you got the time. Pete Thornton, Jack Dalton and let's not forget Vicky would be proud of Mac Guyver! Lol! You never know-, my talent might prove helpful, Mac_Guyver to overthrow Murdoch once and for all! Take care! Edited September 10, 2017 by phpsane Quote Link to comment Share on other sites More sharing options...
Sepodati Posted September 10, 2017 Share Posted September 10, 2017 sql prevention Speaking of incorrect terms.... Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.