Django 如何阻止人们故意重新提交表单?

Django 如何阻止人们故意重新提交表单?,django,apache,ip-address,Django,Apache,Ip Address,我正在使用Ubuntu、Apache和Django构建一个网站。我想阻止人们在我的网站上多次填写和提交特定表格。我知道要阻止一个有决心的用户改变他的IP地址、删除他的cookies等等几乎是不可能的;我所要寻找的是能够阻止临时用户重新提交的东西 在我看来,阻止来自同一IP地址的多个表单提交是实现我所寻找的目标的最佳方式。然而,我不确定我应该怎么做,以及我应该从Apache还是从Django来做。有什么建议吗 编辑:我希望防止有意的重新提交,而不仅仅是无意的重复提交。e、 g.我有一项调查,我想阻

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

在我看来,阻止来自同一IP地址的多个表单提交是实现我所寻找的目标的最佳方式。然而,我不确定我应该怎么做,以及我应该从Apache还是从Django来做。有什么建议吗


编辑:我希望防止有意的重新提交,而不仅仅是无意的重复提交。e、 g.我有一项调查,我想阻止人们多次投票。

有几个国家被提名,还有一些(大多数?)大型跨国公司,其中很多都有几十万用户。通过IP阻止任何东西都是个坏主意


取而代之的是一块小甜饼,这是它能得到的最好的东西。您还可以让用户登录,在这种情况下,您将知道表单是否为该登录而重复提交。

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

对IP地址和/或Cookie进行过滤都很容易,但它们可以防止临时用户由于浏览器故障而意外多次提交同一内容,不耐烦等等


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

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

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


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

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

当用户提交表单时,您将检查cookie值和表单值是否匹配,用户收到的cookie是否以前未用于提交表单,以及引用者id是否与表单的URL匹配。或者,您可以确保在过去2分钟内没有人试图从该IP发帖(速度足够快,对大多数人来说都无关紧要,但速度足够慢,可以减慢机器人程序的速度)

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


基于编辑添加:我将阻止Django框架中的用户。这允许您向用户显示更好的错误消息,并且您只会阻止他们访问该表单。

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

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

如果你想让它抵制故意滥用,那么你最终不仅会得到用户名和密码,还会得到个人识别用户身份的信息,就像银行在你想开户时要求的那样。流血的心脏和左撇子会无休止地为侵犯隐私而哭泣,但事实上,你做的和银行一样,出于同样的原因


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

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

下面的JavaScript使用Mootools,我还没有检查它是否没有bug。我知道JQ语法几乎相同,而rawjs也非常相似,所以这一点应该很清楚

1) 如果表单是通过AJAX提交的,您可以在提交之前进行检查(如果我只是说了一些明显的问题,那么很抱歉)

这真的很简单,而且出人意料的有效,直到他们重新加载页面

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饼干是上述方法的最佳选择,尽管它可以与其他方法结合使用。

谢谢krosenvold。那么,如果一个国家是NAT'ed,那么来自该国家的所有访问都显示相同的IP地址?我在哪里可以找到关于哪些国家/地区被NAT'ed的信息?嗯,他们不会共享一个IP地址,这很可能不是
$('myForm').addEvent('submit', function(){ 
     if(Cookie.read('submitted')){ alert('once only'); return false;}
     else{ Cookie.write('submitted', 1); return true; }
})