Tom10 Posted October 18, 2016 Share Posted October 18, 2016 Hello, I am having issues with the login system that i am currently working on, it is showing login failed on the page when the login details for the user are correct. Login.php <?php require('./includes/connect.php'); error_reporting(E_ALL | E_NOTICE); if ($_SERVER['REQUEST_METHOD'] == "POST") { $username = $_POST['username']; $username = htmlentities($username); $password = $_POST['password']; $password = password_hash($password, PASSWORD_BCRYPT); $query = "SELECT username, password FROM apna_users WHERE username='$username' AND password='$password'"; $result = mysqli_query($mysqli, $query); $row = $result->fetch_array(); if (password_verify($password, $row['password']) && $result->num_rows() > 0) { ?> <html> <h2>Login Successful</h2> </html> <?php } else { ?> <html> <h2>Login Failed</h2> </html> <?php } } ?> <html> <title>Apna Bhaiii - Login</title> <body> <center> <div id="login"> <h1>Login to your account</h1><br> <form action="" method="POST"> <h3>Username:</h3> <input type="text" name="username" placeholder="Enter your username" /> <br> <h3>Password:</h3> <input type="password" name="password" placeholder="Enter your password" /> <br><br> <input type="submit" name="loginbtn" value="Log In" /> <br> </form> <h3>Don't have an account? <a href="register.php">Create one today</a></h3> </div> </center> </body> </html> Register.php (The register script works perfectly) <?php require('./includes/connect.php'); if($_SERVER['REQUEST_METHOD'] == "POST") { $email = $_POST['email']; $email= filter_var($email, FILTER_VALIDATE_EMAIL); $username = $_POST['username']; $username = htmlentities($username); $password = $_POST['password']; $cpassword = $_POST['cpassword']; if (!filter_var($email) || empty($username)) { echo "<b>Email address is invalid.</b>"; } if (empty($username)) { echo PHP_EOL . "<b>Username is empty</b>"; } if (empty($password)) { echo PHP_EOL . "<b>Password is empty or invalid</b>"; } if($cpassword != $password) { die("The passwords do not match!"); } $enc_password = password_hash($password, PASSWORD_BCRYPT); if (mysqli_query($mysqli, "INSERT INTO apna_users (email, username, password) VALUES ('$email', '$username', '$enc_password')")) { echo "Your account has been successfully created."; echo '<meta http-equiv="refresh" content="1;login.php">'; exit(); } else { echo "An error has occured whilst creating your account, please try again later." . PHP_EOL . "If the problem persists please contact support."; } } ?> <html> <title>Apna Bhaiii - Register</title> <style> input {padding: 10px; border-radius: 20px; } #registerbtn1 input {width: 400px;} </style> <body> <center> <div id="register"> <h1>Create your account</h1><br> <form action="" method="POST"> <h3>E-mail Address:</h3> <input type="text" name="email" placeholder="Enter your E-Mail Address" required /> <br> <h3>Username:</h3> <input type="text" name="username" placeholder="Enter your username" required /> <br> <h3>Password:</h3> <input type="password" name="password" placeholder="Enter your password" required /> <br> <h3>Confirm Password:</h3> <input type="password" name="cpassword" placeholder="Confirm your password" required /> <br><br> <input type="submit" name="registerbtn" id="registerbtn1" value="Create" /> <br> </form> </div> </center> </body> </html> Does anyone know why it is doing this?, Thanks Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted October 18, 2016 Share Posted October 18, 2016 (edited) Your code is wide open to SQL injection attacks, and you're misunderstanding password hashing. Use prepared statements for dynamic query input. And fix the password check: password_hash() is only used to create a new hash during registration or a password reset. To verify a password, you fetch the user's hash and call password_verify() with the submitted password and the stored hash. You cannot do a database search with password_hash(), because the same password will always have a different hash due to the random salt. Edited October 18, 2016 by Jacques1 1 Quote Link to comment Share on other sites More sharing options...
Tom10 Posted October 18, 2016 Author Share Posted October 18, 2016 <?php require('./includes/connect.php'); error_reporting(E_ALL | E_NOTICE); if ($_SERVER['REQUEST_METHOD'] == "POST") { $username = $_POST['username']; $username = htmlentities($username); $password = $_POST['password']; if ($query = $mysqli->prepare("SELECT username, password FROM apna_users WHERE username=? AND password=?")) { $query->bindParam("username", $username); $query->bindParam("password", $password); $query->execute(); $query->bind_result($result); $result->fetch(); } if (password_verify($password, $result['password']) && $result->num_rows() > 0) { ?> <html> <h2>Login Successful</h2> </html> <?php $query->close(); } else { ?> <html> <h2>Login Failed</h2> </html> <?php $query->close(); } } ?> <html> <title>Apna Bhaiii - Login</title> <body> <center> <div id="login"> <h1>Login to your account</h1><br> <form action="" method="POST"> <h3>Username:</h3> <input type="text" name="username" placeholder="Enter your username" /> <br> <h3>Password:</h3> <input type="password" name="password" placeholder="Enter your password" /> <br><br> <input type="submit" name="loginbtn" value="Log In" /> <br> </form> <h3>Don't have an account? <a href="register.php">Create one today</a></h3> </div> </center> </body> </html> I have made those changes is this any better?, forgive me if i have mistakes in the code i am quite new to coding just trying to get my head around it Quote Link to comment Share on other sites More sharing options...
Barand Posted October 18, 2016 Share Posted October 18, 2016 The input password will not match that in the user table, so your selection criteria should just be where the username matches. Then verify the retrieved password hash. Quote Link to comment Share on other sites More sharing options...
Tom10 Posted October 18, 2016 Author Share Posted October 18, 2016 The input password will not match that in the user table, so your selection criteria should just be where the username matches. Then verify the retrieved password hash. I have changed that, if ($query = $mysqli->prepare("SELECT username, password FROM apna_users WHERE username=?")) { $query->bindParam("username", $username); $query->execute(); $result->fetch(); } if (password_verify($password, $result['password']) && $result->num_rows() > 0) { ?> <html> <h2>Login Successful</h2> </html> <?php } else { ?> <html> <h2>Login Failed</h2> </html> <?php } When i login, nothing is displayed it's just a blank page. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted October 18, 2016 Share Posted October 18, 2016 (edited) Turn your error reporting on and all the way up. Some mysqli methods you're calling don't even exist, and even those which do exist work completely different. It seems you're somehow trying to mix the mysqli library with the unrelated PDO extension, which of course makes no sense. I gave you a link to the PHP manual which explains in great detail how prepared statements in mysqli work. Read it. Programming is an exact science, so you need to use the actual mysqli API rather than what you think the API should look like. By the way, mysqli sucks compared to PDO, so if there's a chance to switch, I recommend you do that. Clearly you already prefer PDO. Edited October 18, 2016 by Jacques1 1 Quote Link to comment Share on other sites More sharing options...
Tom10 Posted October 18, 2016 Author Share Posted October 18, 2016 Ok thanks @Jacques1 and @Barand Quote Link to comment Share on other sites More sharing options...
Tom10 Posted October 19, 2016 Author Share Posted October 19, 2016 I have turned on error reporting and switched to PDO, However i still recieve a blank page when logging in <?php require('./includes/connect.php'); error_reporting(E_ALL); if ($_SERVER['REQUEST_METHOD'] == "POST") { $username = $_POST['username']; $username = htmlentities($username); $password = $_POST['password']; $query = $mysqli->prepare("SELECT username FROM apna_users WHERE username=?"); $query->bindParam('?', $username, PDO::PARAM_STR, 50); $query->execute(); $row = $query->fetch(PDO::FETCH_ASSOC); if (password_verify($password, $row['password']) && $query->num_rows() > 0) { echo "Login Successful"; } else { echo "Login Failed."; } } ?> <html> <title>Apna Bhaiii - Login</title> <body> <center> <div id="login"> <h1>Login to your account</h1><br> <form action="" method="POST"> <h3>Username:</h3> <input type="text" name="username" placeholder="Enter your username" /> <br> <h3>Password:</h3> <input type="password" name="password" placeholder="Enter your password" /> <br><br> <input type="submit" name="loginbtn" value="Log In" /> <br> </form> <h3>Don't have an account? <a href="register.php">Create one today</a></h3> </div> </center> </body> </html> Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted October 19, 2016 Share Posted October 19, 2016 (edited) to cause all php detected errors to be reported and displayed, you need to set php's error_reporting to E_ALL (it should always be set to this) and set display_errors to ON. these should be set in the php.ini on your development system, so that ALL php errors will be reported (setting them in your code won't help with php syntax errors) and so that you don't need to remember to set them to get php to help you or forget to remove them form your code when you put it onto a live server (you should log all php errors on a live server, not display them to the visitor.) you still have some problems in the posted code - 1) htmlentities() is an OUTPUT function. it is used when you output data to the browser. it is not used on input data and it has nothing to do with data used with an sql query. 2) $mysqli. if you have switched to using the PDO extension, name the variable holding the instance of the PDO class something helpful like $pdo. 3) the first parameter in your bindParam() statement isn't correct. it's either the place-holder number (starting at 1), when using ? place-holders, or its the named place-holder. basic information like this can always be found in the php.net documentation. 4) your sql query is only SELECT'ing the username. therefor, $row['password'] won't exist. this would be throwing an undefined index error once you have php's error_reporting/display_errors set as suggested. 5) you also need to fetch the row and test if the query matched a row, all at the same time. the current code will throw php errors at the $row['password'] if the query doesn't match any row. you can do this - if($row = $query->fetch(PDO::FETCH_ASSOC)) { // the query matched a row, use password_verify() here... } Edited October 19, 2016 by mac_gyver Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted October 19, 2016 Share Posted October 19, 2016 First off, make sure you have the PDO connection parameters right. For example, there's no manual error handling in your code, which means you must make PDO throw an exception in case of an error (otherwise you'd just keep going). A good starting point is this: <?php const DB_HOST = 'localhost'; const DB_USER = '...'; const DB_PASSWORD = '...'; const DB_NAME = '...'; const DB_CHARSET = 'UTF8'; $dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset='.DB_CHARSET; $databaseConnection = new PDO($dsn, DB_USER, DB_PASSWORD, [ PDO::ATTR_EMULATE_PREPARES => false, // use actual prepared statements, don't emulate them PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // make PDO throw an exception in case of an error PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // fetch associative arrays by default ]); The password check itself can be simplified to $userStmt = $databaseConnection->prepare(' SELECT user_id, -- I am guessing here password -- password_hash would be a better name -- add additional columns if needed FROM apna_users WHERE username = :username -- use named parameters for the sake of readability '); $userStmt->execute([ 'username' => $username, ]); $user = $userStmt->fetch(); if ($user && password_verify($password, $user['password'])) { echo 'Credentials correct.'; } else { echo 'Username or password incorrect.'; } 1 Quote Link to comment Share on other sites More sharing options...
Tom10 Posted October 20, 2016 Author Share Posted October 20, 2016 I keep getting this error [20-Oct-2016 20:48:42 UTC] PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] Connection refused' Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted October 20, 2016 Share Posted October 20, 2016 Use the same connection parameters you used for mysqli (which you said worked fine). Double-check the IP address and the port, and make sure the MySQL server is running. 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.