Mlaaa Posted March 6, 2017 Share Posted March 6, 2017 Hi, i have problem with login script. Problem is that i cant login using my username and password. Password i entered in database was with password_hash('admin', PASSWORD_DEFAULT); Here is a code <?php include 'config.php'; if (isset($_SESSION['laa'])) { die('U already logged in. <a href="index.php">Home</a>'); } if (isset($_POST['login'])) { if (isset($_POST['username']) && isset($_POST['password'])) { $username = strip_tags($_POST['username']); $password = strip_tags($_POST['password']); if (empty($username) || empty($password)) { $error = 'Please enter username and password.'; } else { //$password = password_verify($password, PASSWORD_DEFAULT); $stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username AND lozinka = :password"); $stmt->bindParam(':username', $username); $stmt->bindParam(':password', $password); $stmt->execute(); $p = $stmt->fetch(); //password_verify($password, $data['password'])) if ($p['username'] == $username || $p['password'] == $password) { $_SESSION['laa'] = $username; header('Location: index.php'); exit(); } else { $error = 'Invalid username or password.'; } } } else { $error = 'Please enter username and password.'; } } ?> <center> <div style="display:block; margin-top: 10%;"> <p><?php if(!empty($error)) { echo $error; } ?></p> <form action="login.php" method="post"> <p>Username : <input type="text" name="username"></p> <p>Password : <input type="password" name="password"></p> <p><input type="submit" name="login" value="Login"></p> </form> </div> </center> Quote Link to comment Share on other sites More sharing options...
Solution Jacques1 Posted March 6, 2017 Solution Share Posted March 6, 2017 First off, you need to get rid of this strip_tags() nonsense. This can in fact destroy your passwords, because it blindly removes anything that looks like HTML markup. The password_verify() function works like this: if (password_verify($the_password_to_be_checked, $the_stored_password_hash)) { // correct password } else { // wrong password } 1 Quote Link to comment Share on other sites More sharing options...
Mlaaa Posted March 6, 2017 Author Share Posted March 6, 2017 So i need first query to get the password from the database that i can check it with entered password ? Then another query to check if username and password match ? Quote Link to comment Share on other sites More sharing options...
Barand Posted March 6, 2017 Share Posted March 6, 2017 (edited) No. One query to get the stored password hash for the given username. Then verify the given password against that. Edited March 6, 2017 by Barand 1 Quote Link to comment Share on other sites More sharing options...
Mlaaa Posted March 6, 2017 Author Share Posted March 6, 2017 Thanks i used it like this and how works, also problem was in $p['password'] instead or $p['lozinka'] and same for username/korisnicko ime. $stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username"); $stmt->bindParam(':username', $username); $stmt->execute(); $p = $stmt->fetch(); if (password_verify($password, $p['lozinka']) || $p['korisnicko_ime'] == $username) { $_SESSION['laa'] = $username; header('Location: index.php'); exit(); } Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted March 6, 2017 Share Posted March 6, 2017 (edited) Now you're doing an OR check, which means anybody can log-in without a password if they enter a valid username. You need an AND check (&&). // Or rather: Leave out the username check altogether. It's already in the query. Edited March 6, 2017 by Jacques1 1 Quote Link to comment Share on other sites More sharing options...
Mlaaa Posted March 6, 2017 Author Share Posted March 6, 2017 I try this, and it works, if u enter valid username it wont login if u enter valid password and invalid username it wont login. But if i leave WHERE korisnicko_ime = :username AND lozinka = :password this don't works. $stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username"); $stmt->bindParam(':username', $username); $stmt->execute(); $p = $stmt->fetch(); if (password_verify($password, $p['lozinka']) && $p['korisnicko_ime'] == $username) { $_SESSION['laa'] = $username; header('Location: index.php'); exit(); } Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted March 6, 2017 Share Posted March 6, 2017 (edited) Since the password validation happens on the PHP side, you don't need to include it in the query. The username also doesn't need to be validated on the PHP side since that is already done in the query. Unless I'm not thinking clearly...or maybe I missed something, this should be fine: $stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username"); $stmt->bindParam(':username', $username); $stmt->execute(); $p = $stmt->fetch(); if (password_verify($password, $p['lozinka'])) { $_SESSION['laa'] = $username; header('Location: index.php'); exit; } Edited March 6, 2017 by cyberRobot Quote Link to comment Share on other sites More sharing options...
Mlaaa Posted March 6, 2017 Author Share Posted March 6, 2017 (edited) U thinking clearly , if i select username from database it will give me all information about this user as i need, and what i need is to check if that password is valid for that username from query. So your code need to be valid. I try to login with all combination and it only login me with right username and password. So this works. Thanks guys. Edited March 6, 2017 by Mlaaa Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted March 6, 2017 Share Posted March 6, 2017 Side note: since there should only be one entry with any given username, you could optimize the query using the LIMIT clause. $stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username LIMIT 1"); That way MySQL stops looking for more records as soon as it finds the first match. 1 Quote Link to comment Share on other sites More sharing options...
benanamen Posted March 6, 2017 Share Posted March 6, 2017 Side note: since there should only be one entry with any given username, you could optimize the query using the LIMIT clause. $stmt = $dbh->prepare("SELECT * FROM administrator WHERE korisnicko_ime = :username LIMIT 1"); That way MySQL stops looking for more records as soon as it finds the first match. I would think that with a unique index, Mysql already knows there is only going to be one result. 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.