非常奇怪,我希望我只是忽略了一个小细节。我已经一行一行地查了好几天了,但还是不知所措。
因此,当我的页面加载时,我将一个随机变量设置为$_SESSION['rand_token']
,然后将该值放在表单中的一个隐藏字段中。提交表单时,我会根据post值检查会话值,如果它们匹配,我会处理表单提交,如果它们不匹配,我继续加载页面(这意味着表单没有被处理,会话变量再次被更改,隐藏的表单输入得到了新的会话变量)。
问题是,会话变量在执行最后一行代码和执行第二行代码(第一行是session_start();
(在表单提交之后)之间的某个时间发生了变化。我在代码的开头和结尾都有print_r($_SESSION);
,可以看到这一点。
为什么变量在变化!?
<?php
session_start();
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
if (isset($_SESSION['rand_token'], $_POST['rand_token'], $_SESSION['rand_token_expires'])) {
if ($_SESSION['rand_token'] == $_POST['rand_token'] && time() < $_SESSION['rand_token_expires']) {
//Process form
} else {
$danger_msg = 'Token Mismatch<br />Post: ' . $_POST['rand_token'] . '<br />Session: ' . $_SESSION['rand_token'];
}
}
$_SESSION['rand_token'] = md5(microtime(TRUE) . rand(0, 100000));
$_SESSION['rand_token_expires'] = time() + 60 * 60 * 1;
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
?>
<html>
<head>
<title></title>
</head>
<body>
<form>
<input type="hidden" value="<?=$_SESSION['rand_token']?>" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
我将在随后的两次提交后向您显示结果:
第一次打印_r:4f3d097a6a760a4c579f8d8a5b355 ed
代币不匹配帖子:fd6bf788ed3d1393b07472f41b3efd1
令牌不匹配会话:4f3d097a6a760a4c579f8d8a5b355 ed
第二次打印_r:053f22d6126130e88f355fbc5cbbde1f
第一次打印_r:279a85854fc6362d8dc52b0b74d30ef7
代币不匹配帖子:053f22d6126130e88f355fbc5cbbde1f
令牌不匹配会话:279a85854fc6362d8dc52b0b74d30ef7
第二次打印_r:edbee2d6cedbf5581920af353754fed8
我知道这有点令人困惑,但您会看到第二个print_r
应该与下一个第一个print_r
相同。为什么会改变?!
我最近经历了同样的事情,在我的情况下,特别是对于使用时间函数生成的令牌,如果其中一个资产调用在返回404的页面上,它显然重新生成了令牌。因此,检查页面是否有对资产返回404的调用。
这不是一个真正的答案,但您的代码中存在一些错误。我已经更新了它,它运行得非常好:
<?php
session_start();
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
if (isset($_SESSION['rand_token'], $_POST['rand_token'], $_SESSION['rand_token_expires'])) {
if ($_SESSION['rand_token'] == $_POST['rand_token'] && time() < $_SESSION['rand_token_expires']) {
echo "Form should be submitted.";
} else {
$danger_msg = 'Token Mismatch<br />Post: ' . $_POST['rand_token'] . '<br />Session: ' . $_SESSION['rand_token'];
echo $danger_msg;
}
}
$_SESSION['rand_token'] = md5(microtime(TRUE) . rand(0, 100000));
$_SESSION['rand_token_expires'] = time() + 60 * 60 * 1;
echo '<pre>';
print_r($_SESSION);
echo '</pre>';
?>
<html>
<head>
<title></title>
</head>
<body>
<form method="post" action=""> <!-- forgot to set form to post here, defaulted to get instead -->
<input type="hidden" name="rand_token" value="<?=$_SESSION['rand_token']?>" /> <!-- forgot to set name="" here -->
<input type="submit" value="Submit" />
</form>
</body>
</html>