Представьте себе следующий сценарий: пользователь хочет зарегистрироваться на веб-странице и заполнить форму. Пока он заполняет форму, jQuery продолжает проверять регулярное выражение , если поля действительны и т.д.
Принимая электронную почту в качестве основного ключа, который пользователь будет использовать после регистрации для входа в систему, поле электронной почты необходимо проверить с помощью Ajax чтобы пользователь знал, зарегистрировано ли это электронное письмо или нет. Я хочу проверить его с помощью Ajax, чтобы избежать отправки полной формы и ее опустошения, обновления страницы и т.д.
Итак, когда пользователь закончил заполнять поле электронной почты, запрос Ajax отправляется на сервер, что-то вроде следующей ссылки:
example.com/[email protected]
Когда check.php получает электронное письмо, он запрашивает базу данных, если она существует или нет, и возвращает сообщение типа: User already exists
, если пользователь существует, или null
, если пользователь не существует.
Вопрос:, если кто-то прорывается через мой .js и обнаруживает ссылки, похожие на это, они могут использовать эту ссылку для отправки большого количества запросов, чтобы узнать, существуют ли эти случайные электронные письма. Это может привести к интенсивному использованию базы данных или, в худшем случае, даже к сбоям и утечке конфиденциальной информации.
Кто-то может сделать огромный цикл для проверки электронной почты, например:
//Getting the response of the next links
example.com/[email protected] // Returns null
example.com/[email protected] // Returns null
example.com/[email protected] // Returns null
example.com/[email protected] // Returns User already exists
-------------------------------------------- -------------------------------------------------- --------------------------------------
Поскольку я последний раз принимал ответ, я продолжал исследовать это и нашел решение, чтобы избежать такого поведения. Следующий код предназначен для JAVA, но логика может быть применена к любому другому серверному языку.
Прежде чем выполнять ЛЮБОЙ запрос ajax на сервер, я запрашиваю токен на сервере. Этот токен выглядит так: fmf5p81m6e56n4va3nkfu2ns8n
он сделан простым методом, однако он может быть более сложным, но это хорошо.
public String getToken() throws UnsupportedEncodingException {
return new BigInteger(130, new SecureRandom()).toString(32);
}
При запросе маркера сервер не только возвращает токен, но также и небольшой script, который в случае, если кто-то использует браузер для проверки элемента (и браузера navbar), и будет запускаться script, а токен будет очиститься. Сервлет возвращает что-то вроде этого:
_html += "<head>"
+ "<script> "
+ "window.onload=function(){\n"
+ " document.body.innerHTML = \"\";\n"
+ " }"
+ "window.location.href='http://mywebsite.com' "
+ "</script>"
+ "</head>"
+ "<body>"
+ "[" + token+ "]"
+ "</body>"
+ "</html>";
Сначала опустошает тело, затем переместится туда, где мы хотим. javascript/jquery, однако, поймает весь контент как строку, тогда я просто извлекаю строку между [и]. Этот токен доступен только для следующего запроса, поэтому каждый запрос AJAX будет иметь свой уникальный токен. Во втором запросе только что использованный токен удаляется.
После того, как я получу токен, я добавляю его как параметр в любую ссылку, которую я запрашиваю, примерно так:
ajaxRequestObjet = $.ajax({
url: "http://localhost:8084/mywebsite.com/servlet", //<-- local tomcat server
method: "POST",
data: "type=AJAX&page=some-article&token=fmf5p81m6e56n4va3nkfu2ns8n"
});
Этот метод отлично работает с тем, кто проверяет веб-сайт вручную и пытается использовать ссылки, но как насчет серверов java/php/IIS, которые делают это автоматически?
Для этого попросите заголовок! Что-то вроде этого:
boolean isAjax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
Это будет истинно только и только если существует XMLHttpRequest....
Есть одна последняя вещь, о которой нужно помнить. Убедитесь, что 'Access-Control-Allow-Origin' header is NOT present in your app
убедитесь, что любой javascript NOT на вашем сервере не получит ресурсы сервера. Если этот заголовок не существует, хром вернет это:
XMLHttpRequest cannot load http://localhost:8084/mywebsite.com/servlet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
Java-сервер был в tomcat, и у меня был другой apache для этих тестов, это маленький html, присутствующий в apache, который дал ошибку выше:
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script>
ajaxRequestObjet = $.ajax({
url: "http://localhost:8084/mywebsite.com/servlet",
method: "POST",
data: "type=AJAX&page=Token"
});
ajaxRequestObjet.done(function (msg) {
alert(msg);
});
</script>
</head>
<body>
</body>
</html>