Ark*_*rkh 36
使用每次显示表单时生成的唯一标记,并且只能使用一次; 它也可用于防止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>
Run Code Online (Sandbox Code Playgroud)
将它与重定向相结合,这样您就可以保持完美的前后行为.有关重定向的更多信息,请参阅POST/redirect/GET模式.
您可以在第一次单击(使用JavaScript)后禁用该按钮,并检查后端(只是在他们禁用JavaScript的情况下),检查它们是否刚刚提交.
在后端进行检查有很多种不同的方法.一种方法是在第一次单击时设置会话变量,这可以让系统知道它正在处理.如果他们点击第二次,第三次或第四次,那么它只能检查会话变量,如果这表明它已经被点击,它将不会处理.
这只是一个例子 - 你可以用它作为开始.
我建议不要禁用提交按钮,因为在临时网络问题(即请求根本没有通过)的情况下,如果用户选择中止提交(Esc 键/停止按钮),他将无法再次提交网络服务已恢复,而是必须重新加载页面并再次填写所有表单条目。