2009-04-26 95 views
2

我正在使用Ubuntu,Apache和Django构建一个网站。我想阻止人们不止一次在我的网站上填写并提交特定表单。我知道阻止一个确定的用户改变他的IP地址,删除他的cookies等等是几乎不可能的;我正在寻找的东西会阻止临时用户重新提交。如何阻止人们故意重新提交表单?

在我看来,阻止来自同一IP地址的多个表单提交是实现我所需要的最佳方式。但是,我不确定我应该怎么做,以及我是否应该从Apache或Django做到这一点。有小费吗?

编辑:我正在寻找防止故意重新提交,而不是无意双重提交。例如我有一项调查,我想阻止人们多次投票。

回答

3

几个整个国家都是NAT的,还有一些(大多数?)大型跨国公司也是如此,许多公司都有几十万用户。通过IP屏蔽任何东西是不好的想法。

去一个cookie,而不是它会得到。您还可以让用户登录,在这种情况下,您会知道该表单是否为该登录重复提交。

+0

谢谢krosenvold。那么如果一个国家是NAT的,那么来自该国的所有访问都显示相同的IP地址?我在哪里可以找到有关哪些国家/地区已NAT的信息? – RexE 2009-04-26 05:55:43

+0

那么他们不会共享一个*​​单* IP地址,这可能会太有限。期望像整个国家的一个或多个C类网络。据我所知,至少新加坡和泰国是NAT的。我不知道这个信息是否有任何协调的来源;并且事情可能也会改变;) – krosenvold 2009-04-26 06:00:38

1

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

1

过滤IP地址和/或cookie都很容易解决,但它们会防止偶然用户由于浏览器小问题,不耐烦等而多次意外提交相同的东西。

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

1

添加到窗体中隐藏字段中单调增加的id号。

由于每个表单都被提交,所以在“已用”列表/地图(或标记它使用的,或其他,实施细节)中记录该ID。

如果您再次获得相同的ID(如果它已经在您的使用过的地图中),则通知用户它们会双重提交。

1

虽然没有什么是傻瓜证明,我会建议这样的事情:当用户加载与您的窗体上的页面,cookie设置和cookie的值附加一个固定的秘密字符串和md5值这写入表单上的隐藏字段。确保每次用户访问表单时都会生成一个新值。

当用户提交表单时,您检查cookie值和表单值是否匹配,用户所给的cookie尚未用于提交表单,并且引用标识符与表单的URL匹配。可选地,您可以确保在过去的2分钟内没有尝试从该IP发布信息(速度足够快,以至于不会对大多数人造成影响,但速度足以降低机器人的速度)。

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

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

4

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

1

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

如果你想使这个抵抗故意滥用,那么你会不仅用户名和密码就结了,但对于个人识别用户的信息需求,沿东西行银行要求当你想开一个账户。流血的心和左撇子会无休止地侵入隐私,但实际上你和银行完全一样,原因完全一样。

这是很多工作,可能会受到法律的影响。你真的想要这样做吗?

1

以下方法都比较简单,既可以实现也可以破解。任何有Firebug和一点知识的人都不会眨眼。

以下Javascript使用Mootools,并且我没有检查过它是无bug的。 我知道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 Toolbar(或其他浏览器上的equiv's)删除cookie,并重新加载页。

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

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

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

一个瑞士法郎的cookie是上述最好的想法,虽然它可以与其他人结合使用。祝你好运。