非常奇怪,我希望我只是忽略了一个小细节。我已经逐行梳理了这几天,但我仍然处于亏损状态。
所以当我的页面加载时,我将一个随机变量设置为$_SESSION['rand_token']
,然后我将该值放在表单中的隐藏字段中。提交表单时,我会根据post值检查会话值,如果匹配,我处理表单提交,如果它们不匹配,我继续加载页面(这意味着表单没有处理和会话变量再次更改,隐藏的表单输入获取新的会话变量。
问题是会话变量在最后一行代码执行和第二行代码(第一行session_start();
执行时(表单提交之后))之间的某个时间发生变化。我有{ {1}}在代码的开头和结尾看到这个。
为什么变量会发生变化!?
print_r($_SESSION);
我会在2次后续提交后向您展示结果:
1st print_r:4ff3d097a6a760a4c579f8d8a5b355ed
Token Mismatch Post:fd6bf788ed3d1393b087472f41b3efd1
Token Mismatch Session:4ff3d097a6a760a4c579f8d8a5b355ed
2nd print_r:053f22d6126130e88f355fbc5cbbde1f
1st print_r:279a85854fc6362d8dc52b0b74d30ef7
Token Mismatch Post:053f22d6126130e88f355fbc5cbbde1f
Token Mismatch Session:279a85854fc6362d8dc52b0b74d30ef7
2nd print_r:edbee2d6cedbf5581920af353754fed8
我知道这有点令人困惑,但你会发现第二个<?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>
应与下一个print_r
相同。为什么会改变?!
答案 0 :(得分:0)
这不是一个真正的答案,但你的代码中有一些错误。我已经更新了它并且它的工作非常好:
<?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>
答案 1 :(得分:0)
我最近经历过同样的事情,在我的情况下,特别是对于使用时间函数生成的令牌,如果其中一个资产调用 在页面上返回404,它显然重新生成令牌。因此,请检查该页面是否要求资产返回404。