想象一下下一个场景:用户想要注册到网页并填写表格。当他填写表格时,jQuery会通过正则表达式检查字段是否有效等。
将电子邮件作为用户注册后将使用的主键,需要使用Ajax来检查电子邮件字段,以使用户知道该电子邮件是否已注册。我想使用Ajax进行检查,以避免发送完整的表单并清空它,刷新页面等。
因此,当用户结束填写电子邮件字段时,Ajax请求将发送到服务器,类似于下一个链接:
example.com/check.php?email=abcdefg@gmail.com
当check.php收到电子邮件时,它将询问数据库是否存在,并返回一条消息,例如:User already exists用户存在或null用户不存在。
User already exists
null
问题是: 如果有人浏览我的.js并找到与之相似的链接,则他们可以使用该链接发送大量请求,以找出那些随机电子邮件是否存在。这可能会导致数据库的大量使用,甚至在最坏的情况下甚至导致崩溃和私人信息泄漏。
有人可以进行大量的for循环来检查电子邮件,例如:
//Getting the response of the next links example.com/check.php?email=aaaaaaa@gmail.com // Returns null example.com/check.php?email=aaaaaab@gmail.com // Returns null example.com/check.php?email=aaaaaac@gmail.com // Returns null example.com/check.php?email=aaaaaad@gmail.com // Returns User already exists
--------------------------------**
自从我上次接受答案以来,我一直在研究这个问题,并找到了避免这种行为的解决方案。 以下代码适用于JAVA,但该逻辑可以应用于任何其他服务器端语言。
在对服务器执行任何ajax请求之前,我向服务器请求令牌。这个令牌看起来像是fmf5p81m6e56n4va3nkfu2ns8n通过一种简单的方法制成的,但是可以更复杂,但这很好。
fmf5p81m6e56n4va3nkfu2ns8n
public String getToken() throws UnsupportedEncodingException { return new BigInteger(130, new SecureRandom()).toString(32); }
请求令牌时,服务器不仅会返回令牌,还会返回一个小脚本,以防有人使用浏览器检查元素(和浏览器导航栏),这样的脚本将运行并清除令牌。Servlet返回如下内容:
_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都不会获取服务器资源。如果此标头不存在,chrome将返回以下内容:
'Access-Control-Allow-Origin' header is NOT present in your app
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,这是apache中存在的小html,它给出了上面的错误:
<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>
虽然您无法控制此100%,但是有一些选择。
尝试使用与验证码脚本相同的方法。
基本上是当用户加载表单/页面时。您在其PHP会话中生成了一个随机字符串/ id并将其存储..当他们发送ajax请求时,让您的ajax检查还附加该字符串/ id并要求它,然后才允许检查执行,否则返回500或类似的标题。
在会话中使用这种方法,您可以设置允许的检查限制(例如5),并且一旦用户尝试了5次以上的检查,就要求他们重新加载页面或执行人工检查(例如Captcha)。然后重置甚至在1小时内允许每个IP或其他内容总计30个。
还可以使用智能事件在完成Ajax检查时触发,例如,更改字段/选项卡或按下按钮时。或者检测到有效电子邮件时,但是说.com.au将触发两次。
基本上,即使有人嗅探您的JS文件并尝试使电子邮件检查程序自动化,也基本上是这种方式。这将要求他们找到一种方法来附加您生成的字符串/ id,并限制他们执行的请求数量。
除此之外,您还可以轻松完成更多工作。.但是还有其他一些想法。
他们中的大多数人都可以使用PHP会话/ cookie解决问题。例如,如果他们检查并找到3个电子邮件地址。
看看以上建议对您有何帮助,任何问题都可以随时提出。但是周末可能需要我一两天才能回复。。还要研究Captcha脚本如何为它们工作,作为大量源代码。
时间延迟 只会看起来很糟糕/使您的网站显示缓慢/使用户等待响应而造成错误。
您需要限制每个会话/ ip地址的查找数量。否则,总有一种方法可以通过这些检查。.基本上,一旦它们达到极限,就可以了。迫使用户/ ip /会话等待几分钟/小时,并使用验证码脚本进行验证,因此无法编写脚本…
Javascript安全性/隐藏源
尽管您不能真正做到这一点,但是您可以做一些事情,使用带有JS标头的PHP页面生成JS。.so <script src='myjscode.php'></script>,这使PHP可以检查有效的会话。.因此,在一定程度上停止了外部请求。主要用于允许JS仅在成员资格/登录后可用。
<script src='myjscode.php'></script>
多次检查/在这种情况下(如果可能)
根据您的方法,这是否是供用户检查他们是否已经拥有帐户的?如果是的话..您可以将电子邮件支票与他们的姓名/国家/地区/年龄/出生日期等结合使用…因此,他们需要选择两个或三个正确的匹配值,然后才能从ajax调用中获得支票/响应?
也许不是您的情况,但只是想将其也添加进来。