Jag ser att du lagrar en hash av lösenordet i databasen, men till förmån för andra läsare, aldrig lagra lösenord i klartext i databasen. Du vill inte vara som Monster.com.uk !
Du bör använda en starkare hashfunktion än MD5()
. Helst ska du använda SHA256. Den här hashmetoden är tillgänglig i PHP med hash()
funktion.
Du bör också använda ett slumpmässigt salt till lösenordet. Lagra ett annat saltvärde för varje användares konto. Detta hjälper till att besegra ordboksattacker och regnbågstabell attacker.
Du bör lära dig att använda mysqli tillägg istället för det gamla mysql-tillägget. Mysqli stöder parametriserade frågor, så att du kan minska sårbarheten för vissa SQL-injektionsattacker.
Här är ett exempel på kod. Jag har inte testat det, men det borde vara ganska nära att fungera:
$input_login = $_POST['login'];
$input_password = $_POST['password'];
$stmt = $mysqli->prepare("SELECT password, salt FROM customer WHERE login = ?");
$stmt->bind_param("s", $input_login);
$stmt->execute();
$stmt->bind_result($password_hash, $salt);
while ($stmt->fetch()) {
$input_password_hash = hash('sha256', $input_password . $salt);
if ($input_password_hash == $password_hash) {
return true;
}
// You may want to log failed password attempts here,
// for security auditing or to lock an account with
// too many attempts within a short time.
}
$stmt->close();
// No rows matched $input_login, or else password did not match
return false;
Vissa andra personer föreslår att frågan ska testas för login = ? AND password = ?
men jag gillar inte att göra det. Om du gör detta kan du inte veta om sökningen misslyckades eftersom inloggningen inte fanns eller för att användaren angav ett fel lösenord.
Naturligtvis ska du inte avslöja för användaren vad som orsakade det misslyckade inloggningsförsöket, men du kan behöva veta, så att du kan logga misstänkt aktivitet.
@Javier säger i sitt svar att du inte ska hämta lösenordet (eller lösenordshashen i det här fallet) från databasen. Jag håller inte med.
Javier visar anropet md5()
i PHP-kod och skickar den resulterande hashsträngen till databasen. Men detta stöder inte lätt att salta lösenordet. Du måste göra en separat fråga för att hämta denna användares salt innan du kan göra hashen i PHP.
Alternativet är att skicka vanlig text lösenord över nätverket från din PHP-app till din databasserver. Alla som avlyssnar ditt nätverk kan se detta lösenord. Om du har SQL-frågor som loggas kan alla som får tillgång till loggarna se lösenordet. Motiverade hackare kan till och med dumpa för att hitta gamla filsystemsbackupmedia, och kan läsa loggfilerna på det sättet!
Den mindre risken är att hämta hashsträngen för lösenordet från databasen till PHP-appen, jämföra den med hashen för användarens indata (även i PHP-kod) och sedan kassera dessa variabler.