2

我正在使用 Ubuntu、Apache 和 Django 构建一个网站。我想阻止人们在我的网站上多次填写和提交特定表格。我知道要阻止一个坚定的用户更改他的 IP 地址、删除他的 cookie 等等几乎是不可能的。我正在寻找的只是阻止临时用户重新提交的东西。

在我看来,阻止来自同一 IP 地址的多个表单提交是实现我正在寻找的最佳方式。但是,我不确定我应该如何执行此操作,以及我应该从 Apache 还是从 Django 执行此操作。有小费吗?

编辑:我希望防止故意重新提交,而不仅仅是无意的重复提交。例如,我有一个调查,我想阻止人们多次投票。

4

8 回答 8

5

如果您主要关心的是防止有人编写脚本并多次自动提交表单,您可能希望在表单中使用CAPTCHA

于 2009-04-26T06:35:29.800 回答
3

几个国家都被 NAT 了,还有一些(大多数?)大型跨国公司,每个都有几十万用户。通过 IP 阻止任何内容是个主意。

去吃一个饼干吧,这和它会得到的一样好。您还可以让用户登录,在这种情况下,您会知道表单是否为该登录重复提交。

于 2009-04-26T05:44:32.980 回答
1

我将使用会话 ID,并将表单提交存储在带有会话 ID、时间戳和可选的某种表单标识符的表中。然后,当提交表单时,您可以检查表格以确保它在一定时间内没有发生。

于 2009-04-26T05:45:49.153 回答
1

过滤 IP 地址和/或 cookie 都很容易解决,但它们会防止临时用户由于浏览器卡顿、不耐烦等而意外多次提交相同的内容。

如果您想要更好的东西,您可以实现登录,但这当然会阻止很多用户响应。

于 2009-04-26T05:46:44.737 回答
1

在隐藏字段中添加一个单调递增的 id 编号。

在提交每个表单时,将 id 记录在“已使用”列表/地图中(或将其标记为已使用,或其他任何实现细节)。

如果您第二次获得相同的 id(如果它已经在您使用的地图中),请通知用户他们重复提交。

于 2009-04-26T05:47:33.220 回答
1

虽然没有什么是万无一失的,但我会建议这样的事情:当用户加载页面并打开您的表单时,会设置一个 cookie,并且 cookie 的值会附加一个固定的秘密字符串,并将其 md5 值写入表单上的隐藏字段。确保每次用户访问表单时都会生成一个新值。

当用户提交表单时,您检查 cookie 值和表单值是否匹配,用户获得的 cookie 之前没有用于提交表单,以及引用者 ID 是否与表单的 URL 匹配。或者,您可以确保在最后 2 分钟内没有尝试从该 IP 发布(速度足够快,对大多数人来说无关紧要,但速度足够慢,可以减慢机器人的速度)。

为了解决这个问题,用户必须编写一个脚本来加载页面、存储 cookie 并提交正确的值。这比用户只需提交表单要困难得多。

添加基于编辑:我会阻止 Django 框架中的用户。这使您可以向用户显示更好的错误消息,并且您只能阻止他们进入该表单。

于 2009-04-26T06:02:07.540 回答
1

这是一个身份验证和授权的问题,它们是相关的,但并不相同。为了管理授权,您必须首先验证(可靠地识别)用户。

如果您想抵制故意滥用,那么您最终不仅会得到用户名和密码,还会要求提供个人识别用户的信息,就像银行在您开户时要求的那样。流血的心和左撇子会无休止地为侵犯隐私而哭泣,但实际上,您所做的与银行完全相同,并且出于完全相同的原因。

工作量很大,可能会受到法律的影响。你真的想做吗?

于 2009-04-26T06:56:14.397 回答
1

以下方法都相对简单,无论是实现还是破解。任何有 Firebug 和一点知识的人都不会眨眼。

以下 JavaScript 使用 Mootools,我没有检查它是否没有错误。我知道 JQ 语法几乎相同,原始 JS 也足够相似,所以这一点应该很清楚。

1)如果表单是通过 AJAX 提交的,您可以在提交前检查(对不起,如果我只是说明显而易见的)。

var sent = 0;
$('myForm').addEvent('submit', function(){
    if(!sent) this.send(); 
})

这真的很简单,并且在他们重新加载页面之前非常有效。

2) 添加一个 JavaScript cookie。同样,使用 Mootools:

$('myForm').addEvent('submit', function(){ 
     if(Cookie.read('submitted')){ alert('once only'); return false;}
     else{ Cookie.write('submitted', 1); return true; }
})

即使用户重新加载页面,这也会起作用。

3) 添加一个 Python 会话 cookie。我不熟悉 Python,但如果它像 PHP,这将没有方法 2 的优势。在任何一种情况下,用户都可以使用 FireCookie 或 WebDeveloper 工具栏(或它们在其他浏览器上的等效项)删除 cookie 并重新加载页面.

4) 添加一个 Flash cookie(使用 Flex)。这是理想的 - Flash cookie 存储在不同的位置,不明显,并且很难删除。唯一的缺点是您需要创建和嵌入一个很小的 ​​swf。

5)在隐藏字段中存储一个值,并检查该值。可以将散列添加到内部链接,以确保即使页面被导航离开,该值仍保持填充状态。

6) 可以为每个访问者增加一个 URL(或使用 htaccess 的自定义 URL)来玩其他游戏。

swf cookie 是上述方法中最好的方法,尽管它可以与其他方法结合使用。

于 2009-04-26T08:00:35.680 回答