Я пытаюсь создать форму входа. Это мой код HTML-формы
<html> <head> <title>Login</title> <link rel="stylesheet" type="text/css" href="style.css" /> </head> <body> <div class="container login"> <form action="login.php" method="post" class="form-signin" id = "login_form" > <h2 class="form-signin-heading">User Login</h2> <input type="text" name="username" size="20" placeholder="Username"> <input type="password" name="password" size="20" placeholder="Password"></br> <input type="submit" value="Log In" class="btn btn-large btn-primary"> <a href="signup.html">Sign Up</a> </form> </div> </body> </html> <?php } ?>
и это мой php-код
<?php if (isset($_POST) && !empty($_POST)) { session_start(); //connecting to the database include("config.php"); //Storing username in $username variable. $username = mysql_real_escape_string(stripslashes($_POST['username'])); //Storing password in $password variable. $password = mysql_real_escape_string(stripslashes(md5($_POST['password']))); $match = "SELECT id FROM $table WHERE username = '" . $username . "' and password'" . $password . "';"; $qry = mysql_query($match); $num_rows = mysql_num_rows($qry); if ($num_rows <= 0) { echo "Sorry, there is no username $username with the specified password."; echo "Try again"; exit; } else { $_SESSION['user'] = $_POST["username"]; header("location:index.html"); // Page to redirect user after login. } } //else{} ?>
в<?php if (isset($_POST) && !empty($_POST)) { session_start(); //connecting to the database include("config.php"); //Storing username in $username variable. $username = mysql_real_escape_string(stripslashes($_POST['username'])); //Storing password in $password variable. $password = mysql_real_escape_string(stripslashes(md5($_POST['password']))); $match = "SELECT id FROM $table WHERE username = '" . $username . "' and password'" . $password . "';"; $qry = mysql_query($match); $num_rows = mysql_num_rows($qry); if ($num_rows <= 0) { echo "Sorry, there is no username $username with the specified password."; echo "Try again"; exit; } else { $_SESSION['user'] = $_POST["username"]; header("location:index.html"); // Page to redirect user after login. } } //else{} ?>
Ive вставил «mark99» имя пользователя и пароль «1234» в базу данных, но он продолжает давать мою ошибку, говоря, что имя пользователя не существует. Есть идеи?
вы сказали, что вставили 1234 в качестве пароля в таблице?
И в
$password = mysql_real_escape_string(stripslashes(md5($_POST['password'])));
вы имеете пароль, означающий, что он не будет больше 1234 в переменной $ password, поэтому его дает ошибку.
либо удалить md5 (), либо вставить значение md5 1234 в таблицу
Просто ради гвоздики (так что у вас будет представление о том, почему Фред-ии сказал, что не должен использовать этот код). Я собираюсь несколько разобрать это, чтобы, когда я проходил через него (это не персональный копать человека, задающего вопрос, – но просто для того, чтобы дать представление о том, что попытка создать полузащитное приложение на стеке LAMP требует немного заботы и предусмотрительности … и кровавый цинизм, сопряженный с принятием худшего в человечество помогает):
Пункт 1
Не большой, но действительно, если вы собираетесь начать сеанс, вы должны начать сеанс независимо от того, есть ли данные $_POST
или нет. Вероятно, вам понадобится ваш файл конфигурации и начните сеанс сверху, прежде чем что-либо еще.
Не ошибка терминала (поскольку у вас нет проверки сеанса) – просто странно.
Пункт 2
У вас есть выход в этом файле ( echo
), поэтому он должен находиться под корнем документа и доступен в веб-дереве.
include("config.php");
На самом деле это неправильно написано, вероятно, должно быть require_once 'config.php';
(предполагая, что это требуемый файл программы, а не необязательный, который может быть разрешен для отказа), но это не ошибка. Ошибка заключается в том, что у вас есть ваш файл конфигурации внутри вашего корня документа. Конфигурация сервера или простая опечатка в этом файле могут теоретически разрешить вывод содержимого этого файла на экран в виде обычного текста, что потенциально выявит ваши строки подключения к базе данных (и кто знает, что еще) для мира + собака.
Файлы конфигурации должны существовать вне веб-дерева или, в противном случае, внутри каталога, защищенного чем-то вроде .htaccess
Deny from all
. Они никогда не должны быть доступны через HTTP.
Пункт 3
Библиотека mysql
устарела и не должна использоваться вообще; MySQLi или PDO – это путь, идеально связанный с параметрами / значениями:
Лично я получил за PDO.
Очки 4 и 5
$password = mysql_real_escape_string(stripslashes(md5($_POST['password'])));
Во-первых, порядок этого неверен. Вы хешируете $_POST['password']
а затем пытаетесь использовать stripslashes – после его хэши не будет никаких слэшей. Однако, если вы пытаетесь запретить людям использовать косые черты (или что-то еще) в паролях, вам необходимо удалить их перед тем, как хэшировать строку.
Следующий md5
не должен использоваться в качестве алгоритма хэширования паролей, который был признан слабым и может быть грубым принудительным для создания столкновений строк гораздо чаще, чем нужно.
Да, вы должны хранить хэши или «отпечатки пальцев» паролей, а не сами пароли, но в идеале вы хотите солить и хэш (с хотя бы sha1
) этими паролями, а не просто бросать их в функцию md5()
.
См. Например: http://uk3.php.net/mcrypt.
И выполните поиск по «хэш-настройке пароля», используя вашу поисковую систему по выбору.
Пункт 6
SELECT id FROM $table WHERE username = '" . $username . "' and password = '" . $password . "';
Я добавил в =
который отсутствовал в исходном вопросе, но все же не совпал с именем пользователя и паролем в вашем запросе … если кому-то удалось получить SQL-инъекцию в ваше имя пользователя, пароль никогда не будет проверен. Представить:
SELECT user.id FROM user WHERE user.username = 'fred' OR 1 = 1 -- AND user.password = 'abc123'
Лучше выбрать идентификатор пользователя и пароль отпечатка пальца из базы данных, а затем оценить пароль в приложении, а не доверять проверке пароля на уровне базы данных. Это также означает, что вы можете использовать специальный алгоритм хэширования и соления в самом приложении для проверки ваших паролей.
Пункт 7
$_SESSION['user'] = $_POST["username"];
Это просто сохранение имени пользователя в сеансе? Это никоим образом не должно использоваться как «верификатор входа», особенно если на вашем сеансе нет (по-видимому) ничего, чтобы предотвратить угон .
Идентификатор сеанса можно легко обнюхать из файла cookie в режиме реального времени, и это все, что потребуется для «заимствования» чужого имени пользователя. Вы должны хотя бы попытаться уменьшить вероятность захвата сеанса, связав IP-адрес пользователя, строку UserAgent или некоторую другую комбинацию относительно статических данных, которые можно сравнить с каждой страницей … есть недостатки практически любого подхода, хотя (особенно, как я уже нашел, если у вас есть посетители, использующие AOL), но вы можете сделать возможный 99% -ный эффективный сеанс отпечатка пальца, чтобы уменьшить захват с очень небольшим шансом, что сеанс пользователя будет ошибочно сброшен.
В идеале вы также можете создать токен для сеанса для смягчения атак CSRF, когда пользователю необходимо выполнить «привилегированное» действие в базе данных (обновить их данные или что-то еще). Маркер может быть абсолютно случайным и уникальным кодом, хранящимся в базе данных и / или в файле cookie SSL, когда пользователь входит в систему (при условии, что пользователь не может выполнять никаких действий, которые обновляют базу данных за пределами HTTPS, поскольку это просто передаст данные в ясном тексте через Интернет – что было бы плохой идеей ).
Маркер помещается в скрытое поле формы для любых / всех форм и проверяется на значение, хранящееся в файле cookie (или сеансе или базе данных), когда эта форма отправляется. Это гарантирует, что человек, отправляющий форму, будет иметь живую сессию на вашем веб-сайте, по крайней мере.
Это может быть несколько проблем.
Во-первых, в вашем заявлении $ match у вас отсутствует оператор равенства по паролю:
Эта:
$match = "SELECT id FROM $table WHERE username = '".$username."' and password'".$password."';";
Должно быть:
$match = "SELECT id FROM $table WHERE username = '".$username."' and password = '".$password."';";
Во-вторых , вы вставляете пароль в базу данных после его использования с помощью md5?
Если нет, то ваш запрос пытается сопоставить md5 (пароль) с паролем.