For example someone tries to log in with the name “Bob” but there is no Bob in the database. Should the user be notified there is no Bob or should should the program simply say “authentication failed” (I noticed Gmail does this)? This is partly a usability question and partly an efficiency question. As it is now the program queries the database to see if the given username exists and if it does then it queries the database again to find the password hash for the same username (redundant).
//$link is the link to the database storing passwords/usernames
if(userNameExists($uName, $link))
{
if(passwordCorrect($uName, $pass, $link))
echo 'log in successful!';
else
echo 'can\'t log in';
}
else
{
echo 'username doesn\'t exist!';
}
/*This function checks to see if the username exists
INPUT: the userName to check for and a link to the database
OUTPUT: true if username exists
*/
function userNameExists($userName, $link)
{
$result = mysqli_query($link, 'SELECT `userid`
FROM `login`
WHERE `userid` = \''.$userName.'\' LIMIT 1');//need to look into uses of backticks, single quotes, double quotes
return mysqli_num_rows($result) == 1;
}
/*This function checks the password for a given username
INPUT: the userName and password the user entered, and a link to the database
OUTPUT: true if the given password matches the one in the database
*/
function passwordCorrect($userName, $givenPassword, $link)
{
$result = mysqli_query($link, 'SELECT `password`
FROM `login`
WHERE userid = \''.$userName.'\' LIMIT 1');
$retrievedPassword = mysqli_fetch_array($result);
if(password_verify($givenPassword, $retrievedPassword['password']))
return true;
else
return false;
}
Should I instead only use passwordCorrect() and if mysqli_query() returns false this implies the username does not exist (admittedly I don’t like these solutions because it could mean something else has gone wrong, doesn’t it?)?
You should not provide details why the login failed (user does not exists or password is wrong), as this increases security. Unless usernames are visible when one is not logged in (which is actually insecure and should not be the case..!)
Advantage is that you indeed can use a single query to get the hash for the given username. If you do not get a result, the username is wrong (and the login failed), otherwise you can (directly) check the hash (to see if the password is wrong).