好吧,在我的网站上,我使用PHP唯一的表单令牌来防止CSRF攻击。唯一的表单令牌和表单令牌验证功能如下:
// generate new token for every form
function generate_Form_Token($form_name) {
$token = md5(uniqid(microtime(), true));
$_SESSION[$form_name.'_token'] = $token;
return $token;
}
// validate form request
function verifyForm ($form, $url){
// call the form processing page
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
if($actual_link !== SITE_URL."$url")
return false;
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest')
return false;
if(!isset($_SESSION[$form.'_token']))
return false;
if(!isset($_POST['_token']))
return false;
if($_SESSION[$form.'_token'] !== $_POST['_token'])
return false;
return true;
}
现在,如果我在一个页面中有一个表单,那么它将成功验证表单。
但是在我的网站上,我有一个名为create-menu.php
的页面,我在这里使用4个表单,所以这个4个表单将生成4个唯一的表单令牌,我在每个4个表单中使用以下输入字段:
<input type="hidden" name="_token" value="<?php echo generate_Form_Token('menu_creation'); ?>">
但问题是当我在process.php
页面中验证表单(使用Ajax)时。在该页面中,只有第一个表单正在验证,但其他3个表单正在向我显示错误消息(如果表单令牌与会话不匹配,则为我的自定义错误消息)。
process.php页面
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if(verifyForm('menu_creation','menu-creation')) {
// my code.....
}
}
我如何解决这类问题?有人能帮我吗?非常感谢。
调用一次生成标记的函数。将返回值存储在变量中。在每个表单中使用该变量。