Некоторые вещи для рассмотрения:
1
if(isset ($_POST['submit'])) {
Это работает только в том случае, если ваша кнопка отправки в форме имеет name="submit"
элемент ввода, что может не всегда иметь место. Вы можете забыть добавить его к кнопке отправки, например. Лучшая проверка:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
Это всегда верно, если форма была отправлена, независимо от того, какие поля были отправлены или кнопки были нажаты.
2
if ($username&&$password){
может быть лучше переписано как:
if(!empty($username) && !empty($password)) {
Лучше всего прямо указать, что вы хотите, чтобы они были непустыми, что впоследствии облегчит понимание другими.
3
$ login_query = "ВЫБРАТЬ * ИЗ ПОЛЬЗОВАТЕЛЕЙ, ГДЕ username = '$ username'";
Это просто умоление о внедрении SQL-кода в вашу систему. Существует множество ресурсов о том, что такое SQL-инъекция и как ее обойти, поэтому я не буду здесь ее перефразировать. Пожалуйста, исправьте это до того, как это произойдет (и подумайте о том, что произойдет, если кто-то попытается войти с ' OR 1=1
в качестве своего имени пользователя.
4:
while ($row = mysqli_fetch_assoc($result))
Если ваша таблица построена правильно, из запроса возможны только два результата. Ничего, потому что имя пользователя не существует; или ОДНА строка, представляющая данные этого пользователя. Нет необходимости делать цикл для получения всех подходящих имен пользователей. Конечно, возможно, вы разрешаете несколько учетных записей «Джона Смита» и идентифицируете их по паролю, но это небезопасно. Что, если пароль Джона Смита № 1 очень похож на пароль Джона Смита № 2, и один из двух «угадывает» другой, сделав опечатку? Теперь один человек вошел в аккаунт другого.
5
Вместо выполнения die()
, если что-то не совпадает, считается вежливой практикой повторно отображать отправленную форму, чтобы пользователь мог повторить попытку. Ваша система требует, чтобы пользователь нажал на спину, чтобы вернуться к форме входа в систему, прежде чем он сможет повторить попытку Вы должны реструктурировать код так, чтобы в случае возникновения ошибки эта ошибка отображалась ДОЛЖНО с формой входа в систему.
6
echo "
<div id='login'>
....
</table></form></div>";
Генерация длинной текстовой строки, подобной этой, является болезненной, особенно если вам приходится использовать кавычки внутри. Вместо этого используйте HEREDOC, который специально предназначен для построения многострочных строк. В качестве бонуса он действует как строка в двойных кавычках, поэтому вы можете интерполировать переменные в строку по мере ее создания:
echo <<<EOL
<div id="login">
....
</table></form></div>
EOF
7
Вместо отображения «Вы вошли в систему» со ссылкой на страницу профиля, почему бы просто не перенаправить пользователя на страницу профиля автоматически?
Итак, после всего этого ваш скрипт будет выглядеть примерно так:
<?php
$error = NULL;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$username = $_POST['name'];
$password = $_POST['pw'];
if (!empty($username) && !empty($password) {
$qusername = mysql_real_escape_string($username);
$qpassword = mysql_real_escape_string($password);
$query = <<<EOL
SELECT *
FROM users
WHERE (username = $qusername) AND (password = $qpassword)
EOL;
$stmt = mysql_query($query);
if (mysql_num_rows($stmt) == 1) {
// store user details in session here
redirect("profile.php?userID=$id");
} else {
$error = "Invalid username or password";
}
} else {
$error = "Must specify both username and password";
}
}
?>
<html>
<body>
<?php if (!empty($error)) { ?>
<h3><?php echo $error ?></h3>
<? } ?>
<form ...>
<table ...>
<tr>
<td><input type="text" name="name" value="<?php echo htmlspecialchars($name) ?>" /></td>
</tr>
<tr>
<td><input type="password" name="pw" /></td>
</tr>
<table>
<input type="submit" value="Login" />
</form>