Вход

Просмотр полной версии : AJAX обработка форм


ПавелСедой
18.02.2017, 15:44
Столкнулся с проблемой при выполнении AJAX обработки форм:

Форма:
<form method="post" action="functions/auth.php">
<ul id="inputEmailPass">
<h3>Вход</h3>
<p id="messageAuth">Неверный логин или пароль!</p>
<li><center><input type="text" name="authLogin" id="authLogin" placeholder="Введите логин"></center></li>
<li><center><input type="password" name="authPass" id="authPass" placeholder="Пароль"></center></li>
<ul id="listAuth">
<li><input type="checkbox" name="rememberMe" id="rememberMe"><label for="rememberMe">Запомнить меня</label></li>
<li><a id="remindPass" href="#">Забыли пароль?</a></li>
</ul>
<p align="right" id="buttonAuth"><a>Вход</a></p>
</ul>
</form>

$(document).ready(function() {
var authLogin = $("#authLogin").val();
var authPass = $("#authPass").val();

if(authLogin === "" || authLogin.length > 30) {
$("#authLogin").css("borderColor", "#FDB6B6");
sendLogin = 'no';
} else {
$("#authLogin").css("borderColor", "#DBDBDB");
sendLogin = 'yes';
}

if(authPass === "" || authPass.length > 15) {
$("#authPass").css("borderColor", "#FDB6B6");
sendPass = 'no';
} else {
$("#authPass").css("borderColor", "#DBDBDB");
sendPass = 'yes';
}

if($("#rememberMe").prop('checked')) {
authRememberMe = 'yes';
} else {
authRememberMe = 'no';
}

if(sendLogin === 'yes' && sendPass === 'yes') {
$("#buttonAuth").hide();
$.ajax({
type: "POST",
url: "functions/auth.php",
data: "login=" + authLogin + "&pass=" + authPass + "&rememberMe=" + authRememberMe,
dataType: "html",
cache: false,
success: function(data) {
if(data == 'yesAuth'){
location.reload();
} else {
$("#messageAuth").slideDown(400);
$("#buttonAuth").show();
}
}
});
}
});

});

и PHP обработчик:
<?php
require_once "functions.php";

if($_SERVER["REQUEST_METHOD"] == "POST") {
$login = strtolower(clearString($_POST['login']));
$pass = strrev(md5(clearString($_POST['pass'])));
$pass = strtolower("ah40d".$pass."m6me9w");

if($_POST['remrmberMe'] == 'yes'):
setcookie('rememberMe', $login.'+'.$pass, time() + 3600*24*31, "/");
endif;

connectDB();
$query = $mysqli->query("SELECT * FROM `users` WHERE `login`='$login' AND `pass`='$pass'");
closeDB();
$rows = $query->num_rows;
if($rows > 0):
$userSession = resultToArray($query);

$_SESSION['auth'] = 'yesAuth';
$_SESSION['authPass'] = $userSession['pass'];
$_SESSION['authLogin'] = $userSession['login'];
$_SESSION['authSurname'] = $userSession['surname'];
$_SESSION['authName'] = $userSession['name'];
$_SESSION['authPatronymic'] = $userSession['patronymic'];
$_SESSION['authAddress'] = $userSession['address'];
$_SESSION['authPhone'] = $userSession['phone'];
$_SESSION['authEmail'] = $userSession['email'];

echo 'yesAuth';
else: echo 'noAuth';
endif;
}

Обработчик PHP проверял отдельно (менял POST на GET и передавал переменные) - возвращает "yesAuth", а вот все вместе не работает - пишет "не верный логин или пароль"... :blink: :blink:
В чем может быть проблема? я как то не правильно передаю формы?:help: :help: :help:

laimas
18.02.2017, 18:44
$pass = strrev(md5(clearString($_POST['pass'])));

Это зачем? В базе пароли не хранят, в базе хранят хеш пароля, ибо если вот так делать запросы к базе как у вас

$login = strtolower(clearString($_POST['login']));
$pass = strrev(md5(clearString($_POST['pass'])));

$mysqli->query("SELECT * FROM `users` WHERE `login`='$login' AND `pass`='$pass'");

то пароли всех ваших пользователей будут у меня в кармане.

ПавелСедой
18.02.2017, 20:37
Спасибо за совет, учту, но вопрос то не в этом..

laimas
18.02.2017, 20:41
вопрос то не в этом..

Это как раз главное, делайте сначала это как положено, так как и проверка при этом будет совсем иная.

Открывайте руководство РНР и читайте о подготовленных запросах misqli. Если планируется использовать версию РНР не ниже 5.5, то можно использовать Password Hashing функции.

Сделаете это, а уж потом почему, если только они будут.

ПавелСедой
18.02.2017, 23:29
Сделаете это, а уж потом почему, если только они будут.

<?php
require_once "functions.php";

if($_SERVER["REQUEST_METHOD"] == "POST") {
$login = strtolower(clearString($_POST['login']));
$pass = strtolower(clearString($_POST['pass']));

if($_POST['remrmberMe'] == 'yes'):
setcookie('rememberMe', $login.'+'.$pass, time() + 3600*24*31, "/");
endif;

connectDB();
$quer = $mysqli->query("SELECT * FROM `users` WHERE `login`='$login'");

$userSession = $quer->fetch_array(MYSQLI_ASSOC);
$passForCrypt = crypt($pass ,$userSession['pass']);

if($userSession['pass'] == $passForCrypt):
$_SESSION['auth'] = 'yesAuth';
$_SESSION['authPass'] = $userSession['pass'];
$_SESSION['authLogin'] = $userSession['login'];
$_SESSION['authSurname'] = $userSession['surname'];
$_SESSION['authName'] = $userSession['name'];
$_SESSION['authPatronymic'] = $userSession['patronymic'];
$_SESSION['authAddress'] = $userSession['address'];
$_SESSION['authPhone'] = $userSession['phone'];
$_SESSION['authEmail'] = $userSession['email'];
$quer->close();

echo 'yesAuth';
else: echo 'noAuth';
endif;
closeDB();
}

Вот сделал так, всё равно результат не изменился...:cray:

laimas
19.02.2017, 05:07
if($("#rememberMe").prop('checked')) {
authRememberMe = 'yes';
} else {
authRememberMe = 'no';
}

Выбросить, а на сервере проверка выбранного флажка, это if(isset($_POST['rememberMe'])), ибо не выбранные флажки клиентом на сервер не передаются.

Вы не сделали основного, что требовалось.

ПавелСедой
19.02.2017, 11:36
Вы не сделали основного, что требовалось.

В таком случае я не могу понять что требуется сделать, объясните пожалуйста... Почему не подходит crypt()? Насколько я понял он же генерирует хэш с солью и уже их я храню в базе, не так?

ПавелСедой
19.02.2017, 11:42
Выбросить, а на сервере проверка выбранного флажка, это if(isset($_POST['rememberMe'])), ибо не выбранные флажки клиентом на сервер не передаются.


Сделал так, теперь когда нажимаю кнопку "Вход" - она прячется, а дальше вообще ничего не происходит.. Ошибку о не правильно логине или пароле не выдает и страница не перезагружается..

Malleys
19.02.2017, 12:51
Вам нельзя сделать кнопку отправки? <input type="submit">
Я не знаю, что у вас там отправлялось... без кнопки отправки.

Вы там написали скрипт, но он только один раз после загрузки документа срабатывает!
$(document).ready(function() {
// это сработает сразу, а вам надо когда пользователь отправляет форму
});

Проверил с <?php

print_r($_POST);
Теперь работает...
Array
(
[login] => йцукен
[pass] => 12345
[rememberMe] => no
)

При проверке в форму добавил <input type="submit">


$(document).ready(function() { ... });

заменил на

$("form").on("submit", function() {
...
return false;
});

laimas
19.02.2017, 13:12
Почему не подходит crypt()? Насколько я понял он же генерирует хэш с солью и уже их я храню в базе, не так?

А где здесь $pass = strrev(md5(clearString($_POST['pass']))); crypt(), тут md5 перевернутая, где соль? ) Подойдет конечно, но если РНР 5.5 то то что я говорил. Ну а самое страшное, это дыра в запросе, да еще к такой таблице.

ПавелСедой
19.02.2017, 13:47
Вам нельзя сделать кнопку отправки? <input type="submit">
Я не знаю, что у вас там отправлялось... без кнопки отправки.


Пропустил строчку когда копировал свой код...


$(document).ready(function() {
$("#buttonAuth").click(function() {
var authLogin = $("#authLogin").val();
var authPass = $("#authPass").val();
var authPass = '';

if(authLogin === "" || authLogin.length > 30) {
$("#authLogin").css("borderColor", "#FDB6B6");
sendLogin = 'no';
} else {
$("#authLogin").css("borderColor", "#DBDBDB");
sendLogin = 'yes';
}

if(authPass === "" || authPass.length > 15) {
$("#authPass").css("borderColor", "#FDB6B6");
sendPass = 'no';
} else {
$("#authPass").css("borderColor", "#DBDBDB");
sendPass = 'yes';
}

if($("#rememberMe").prop('checked')) {
authRememberMe = 'yes';
} else {
authRememberMe = 'no';
}

if(sendLogin == 'yes' && sendPass == 'yes') {
$("#buttonAuth").hide();
$.ajax({
type: "POST",
url: "functions/auth.php",
data: "login=" + authLogin + "&pass=" + authPass + "&rememberMe=" + authRememberMe,
dataType: "html",
cache: false,
success: function(data) {
if(data === 'yesAuth'){
location.reload();
} else {
$("#messageAuth").slideDown(400);
$("#buttonAuth").show();
}
}
});
}
});

});


Вам нельзя сделать кнопку отправки? <input type="submit">
Я не знаю, что у вас там отправлялось... без кнопки отправки.
Дело в том что если делаю так как Вы говорите - то после нажатия на кнопку входа происходит переход на php страницу обработчика, а мне нужно так что бы оставалась та же страница..

ПавелСедой
19.02.2017, 13:48
Ну а самое страшное, это дыра в запросе, да еще к такой таблице.
В чём дыра? Подскажите, где я могу прочитать как правильно сделать? Буду очень благодарен

laimas
19.02.2017, 14:04
то после нажатия на кнопку входа происходит переход на php страницу

$("#buttonAuth").click(function() { - удалить, и лучше так

$("form").submit(function(e) {
e.preventDefault();
.....


В чём дыра? П

В том, что данные извне подставляются непосредственно в запрос, а это sql-инъекция. То есть я запросто могу полем формы приклеить к запросу мне нужное и вытяну пароли всех ваших пользователей, как пить дать.

Чтобы этого не произошло, данные извне обязательно нужно экранировать или приводить и известному типу. Чтобы не париться самому, mysqli берет на себя эту заботу, читать тут (http://fi2.php.net/manual/ru/mysqli.prepare.php).

Вот это strtolower(clearString($_POST['login'])); бесполезное, ибо MySQL не оперирует регистром при запросах. Чтобы учитывать регистр, нужно тогда указывать бинарный режим, что для логина совсем не нужно, если не хотите на сервер иметь клонов, а при проверке хеш пароля вредно.

ПавелСедой
19.02.2017, 15:50
Чтобы этого не произошло, данные извне обязательно нужно экранировать или приводить и известному типу. Чтобы не париться самому, mysqli берет на себя эту заботу, читать тут.

Спасибо большое, разберусь что бы работала AJAX авторизация и буду работать с запросами)))

$("#buttonAuth").click(function() { - удалить, и лучше так

$("form").submit(function(e) {
e.preventDefault();
.....


Сделал так, убрал пока что обработку чекбокса "запомнить меня", к сожалению все равно возвращает "Неверный логин или пароль"...
Попробовал без "preventDefault" - обработчик php печатает "yesAuth", для достоверности после этого сделал печать массива "POST", логина и пароля который присваивается из POST и логина с паролем из базы данных.. Array ( [authLogin] => ghumo [authPass] => gKGJFRAz )
DB - $1$/25.ai/.$CbF.3WwY.NXi3skZevV9O/
POST - $1$/25.ai/.$CbF.3WwY.NXi3skZevV9O/
DBuser - ghumo
POSTuser - ghumo
yesAuth PHP выходит отрабатывает всё верно.. Но вот из формы авторизации все равно ничего не выходит...
http://image.prntscr.com/image/22bffa8d69b34cadb6567eb5dcfc821e.png

laimas
19.02.2017, 16:07
Попробовал без "preventDefault" - обработчик php печатает "yesAuth"

У браузера есть действия по умолчанию, при активации формы будет ее отправление. preventDefault() отменяет это действие, в противном случае форма будет отправлена естественным путем и никакой Ajax отправки не произойдет.

Что касается проверки, то это хромает логика или неверны данные. Смотреть отладчиком.

ПавелСедой
21.02.2017, 10:00
Решил проблему следующим способом:

success: function (data) {
if(data.trim() === 'yesAuth') location.reload();
else $("#messageAuth").slideDown(400);
}
Добавил .trim() к data. Видимо были лишнее пробелы)