2009-04-26 101 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是上述最好的想法,雖然它可以與其他人結合使用。祝你好運。