如何防止多个表单提交在PHP中的多个点击
如何防止多个表单提交在PHP中的多个点击
每次显示表单时都使用唯一的令牌,并且只能使用一次; 防止CSRF和重放攻击也是有用的。 一个小例子:
<?php session_start(); /** * Creates a token usable in a form * @return string */ function getToken(){ $token = sha1(mt_rand()); if(!isset($_SESSION['tokens'])){ $_SESSION['tokens'] = array($token => 1); } else{ $_SESSION['tokens'][$token] = 1; } return $token; } /** * Check if a token is valid. Removes it from the valid tokens list * @param string $token The token * @return bool */ function isTokenValid($token){ if(!empty($_SESSION['tokens'][$token])){ unset($_SESSION['tokens'][$token]); return true; } return false; } // Check if a form has been sent $postedToken = filter_input(INPUT_POST, 'token'); if(!empty($postedToken)){ if(isTokenValid($postedToken)){ // Process form } else{ // Do something about the error } } // Get a token for the form we're displaying $token = getToken(); ?> <form method="post"> <fieldset> <input type="hidden" name="token" value="<?php echo $token;?>"/> <!-- Add form content --> </fieldset> </form>
将它与redirect结合起来,让你保持完美的向后和向前的行为。 有关redirect的更多信息,请参阅POST / redirect / GET模式。
你可以在第一次点击(使用JavaScript)之后禁用button,并且在后端检查(以防他们的JavaScript被禁用),检查它们是否刚刚提交。
有很多不同的方式来检查后端。 一种方法是在第一次点击会话variables时设置会话variables,这可以让系统知道正在处理。 如果他们点击第二次,第三次或第四次,那么它只能检查会话variables,如果它表示已经被点击,则不会处理。
这只是一个例子 – 你可以用它作为开始。
你可以添加这样的东西
<input type="hidden" name="form-token" value="someRandomNumber">
然后在后端,你有一个保存的方式来识别多个表单提交。 当然,这个解决scheme有一些包袱,因为你必须删除你已经完成处理的表单标记等。
在大多数情况下,一个禁用的forms做窍门,例如通过禁用button或通过添加return false
到表单提交事件(不知道这是否工作,没有jQuery,虽然)。
我build议不要禁用提交button,因为在出现临时性networking问题(即请求还没有完成)的情况下,如果用户select中止提交(Esc键/停止button),则一旦networking服务已经恢复,而不得不重新加载页面并重新填写所有表单条目。
这是你的问题最常见的答案
if (isset($_COOKIE['FormSubmitted'])) { die('You may only submit this form once per session!'); }