如何在 PHP 中多次单击时防止多次提交表单

2022-08-30 18:13:46

如何在 PHP 中多次单击时防止多次提交表单


答案 1

使用每次显示表单时生成的唯一令牌,该令牌只能使用一次;它对于防止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>

将其与重定向相结合,以便您保持完美的向后和向前行为。有关重定向的详细信息,请参阅 POST/重定向/GET 模式。


答案 2

您可以在第一次单击后禁用该按钮(使用JavaScript),还可以在后端进行检查(以防万一他们禁用了JavaScript),以检查他们是否最近提交。

在后端执行检查的方法有很多种。一种方法是在他们第一次单击会话变量时设置它,这可以让系统知道它正在处理。如果他们单击第二次、第三次或第四次,则只需检查会话变量,如果这表明它已被单击,则不会处理。

这只是一个例子 - 你可以用它作为开始。


推荐