2010-07-22 29 views
1

我花了數週時間處理表單上的雙重提交保護。直接,存儲令牌的會話方法不起作用。表單上的令牌方法,雙重提交問題

Sessions可以正常工作以刷新頁面或某人回顧他們的歷史記錄......但通過單擊按鈕多次進行的經典雙擊提交無法使用會話進行阻止。

我在思考腳本無法快速檢查/寫入/刪除會話,以便在多次單擊處理的毫秒內處理錯誤。

是否有另一種服務器端方法來防止此問題?

回答

3

看來你需要一個能夠避免競爭條件的獨立令牌存儲。爲了得到這個工作,有幾種解決方案可用,其中一種更容易實現:

  • 將令牌存儲在數據庫中,並帶有(tokencode,claimid)字段。
  • 接收時,請將claimid設置爲microtime(),可能甚至包括進程ID或散列,只要它非常確定在相互之間開始的類似進程中是唯一的。
  • 嘗試聲明令牌:UPDATE tokens SET claimid = <id> WHERE tokencode=tokencode AND claimid IS NULL
  • 更改以前的語句(或做一個選擇)的計數行。
  • 如果某行發生了變化和/或您的microtime()'d claimid:您是贏家,請繼續執行操作
  • 如果沒有任何更改或令牌具有錯誤的claimid,則不會執行該操作。
+0

你先生,都不錯。這似乎工作。我在表單類中恢復了令牌檢查,但使用數據庫而不是會話。我對你的建議做了一個小小的變體 - 包含id/token/used的表,插入帶有唯一標記的行並在表單上使用used = false,檢查在提交時是否使用了行,以及在完成時更新了used = true的行。 – swt83 2010-07-23 00:09:09

+1

您的修改從原子性中移除了許多努力:不要等待將true設置爲true,並用唯一的id聲明它。在檢查和設置爲true的5ms之間,可能會出現約10個其他進程。當然,整個會話寫入/加載的可能性較小,但仍然如此。 – Wrikken 2010-07-23 00:18:16

+0

我很欣賞這種差異,並做出了改變。非常感謝您的幫助。 – swt83 2010-07-23 00:42:02