我已经使用PHP定义了一个存储令牌的会话,如下所示:
$_SESSION['token'] = sha1(uniqid(mt_rand(), true));
当我想阅读此会话时,我在Chrome或Firefox中没有任何问题。但是在IE中,它会在重新生成之前变为其他东西。例如,如果我将其值存储在表单的隐藏字段中并按照以下方式提交:
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>" />
我会在下一页的IE中得到这个结果:
echo $_SESSION['token']; // shows 1b05fab5ec11f1d50713aea6e74f84727d29b4a3
echo $_POST['token']; // shows e8fac6d55b04d1752f37ecde953f7f08b112ccca
如果我在创建后立即打印$_SESSION['token']
,或者甚至在其创建页面结束时打印<form action="process/login.php" method="post">
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>" />
<label>Email: </label><input type="text" name="email" />
<div class="space"></div>
<label>Password: </label><input type="password" name="password" />
<div class="space"></div>
<input type="submit" value="Login" class="button" />
</form>
,它会准确地显示内容并且没有任何问题。
这是什么问题?
修改
这是我的表格:
{{1}}
答案 0 :(得分:4)
由于PHP和会话存储是服务器端而IE显然是客户端,因此问题不在于您的会话代码。
会话通常由cookie(会话cookie)或POST / GET变量跟踪。默认情况下,在PHP中,此值名为PHPSESSID。
或许,在你的情况下,链接到你的服务器端会话的会话cookie或POST / GET变量在IE中没有好转。如果是cookie,它可能与cookie设置以及是否允许cookie有关。如果是POST / GET,可能是因为你的HTML不像IE不喜欢的那样,但其他浏览器也能理解。
现在,一旦IE中的值丢失,PHP就会在每个请求上为该浏览器分配一个新会话,并在每个请求上重新生成会话令牌。但你的隐藏字段也会记住旧标记......
如果您向我们展示更多代码(您可以编辑您的问题),我可以编辑我的答案,为您提供更多详细信息。
修改强> 您可以首先向我们展示与会话和会话cookie有关的相关php.ini设置行。并通过仔细检查您的IE cookie设置。具体来说,我想知道你是否设置了一个cookie_path,使cookie只在同一个目录中可用。
也许您甚至安装了IE安全设置或插件来阻止Cookie。因此,请尝试检查您的IE设置并禁用所有加载项并再次测试。
同时检查第一页(设置会话)和第二页(读取会话)是否具有完全相同的域名。
因此,例如第一页中的www.yourdomain.com
,不应该是第二页上的yourdomain.com
(没有www)或www.yourdomain.com.
(末尾有一个额外的点)。< / p>
答案 1 :(得分:2)
我认为在您的表单提交后,您可能正在创建另一个令牌值。
使用
if(!isset($_POST['token'])){
$_SESSION['token'] = sha1(uniqid(mt_rand(), true));
}
答案 2 :(得分:1)
我会尝试将输入的名称更改为其他内容,也许IE正在使用令牌名称做一些奇怪的事情。搜索网,但没有提到这一点,但只是为了安全起见,并删除此选项,我会这样做。
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>" />
为:
<input type="hidden" name="my_session_token" value="<?php echo $_SESSION['token']; ?>" />
并尝试将$_SESSION['token']
更改为$_SESSION['my_session_token']
,如上所述
答案 3 :(得分:1)
我几乎可以肯定您要分配$_SESSION['token']
两次。它可能是执行两次的同一行代码,或者您也已将该变量分配给其他地方。为了找到问题,您需要将函数定义为分配会话条目的包装器。然后调用函数而不是直接赋值变量。这是示例代码:
function assign_token()
{
$_SESSION['token'] = sha1(uniqid(mt_rand(), true));
}
但是您需要确保永远不要在代码中的任何位置直接分配token
。并调用此函数。一旦你完成了这个,如果你有一个调试器,你需要做的就是在这个函数中设置一个断点,看看它被调用了多少次,从哪里开始。
但是如果您没有安装调试器,或者更糟糕的是,如果分配不是在单个请求中而是在两个请求中,则需要修改您的函数:
function assign_token()
{
file_put_contents('/tmp/assign_token.txt', time() ."\n". print_r(debug_backtrace(), true), FILE_APPEND);
$_SESSION['token'] = sha1(uniqid(mt_rand(), true));
}
添加的行将帮助您每次调用函数时进行跟踪。即使它在两个单独的请求中被调用两次,您也可以通过FILE_APPEND
和time()
来识别它们。第一个附加到文件(显然),因此日志条目不会相互覆盖,第二个有助于知道您的日志的两个条目是否在同一请求中。
这就是我所拥有的一切。最后,您可能希望设置日志条目的样式,使其更具可读性。
答案 4 :(得分:0)
我会做更多的事情:
md5(uniqid($_SERVER['REMOTE_ADDR'], true))
确保令牌永远是唯一的。
答案 5 :(得分:0)
如果我错了,请纠正我,但我已经在Chrome FF和IE 7中测试了下面的代码,似乎IE没有任何问题。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method="POST" action="/">
<?php
session_start();
if(!$_SESSION['token']){
$_SESSION['token'] = sha1(uniqid(mt_rand(), true));
}
?>
<input type="hidden" value="<?php echo $_SESSION['token']; ?>" name="token"/>
<button type="submit" name="send">Send</button>
<?php
if(!empty($_POST)){
var_dump($_POST);
var_dump($_SESSION['token']);
}
?>
</form>
</body>
</html>
如果您有php版本&gt; = 5.4尝试使用此命令()在php中设置内置服务器:
php -S localhost:88 -t /path/to/your/app
假设您正在本地计算机上进行测试。 Mayby服务器上的apache + php堆栈有问题。
答案 6 :(得分:0)
检查 sha1(uniqid(mt_rand(),true))的值。 IE的名称包含&#39; - &#39;或者&#39; _&#39; - 他们无法维持会话!我过去曾两次遇到过这个问题,而且我总是花费数周的时间才弄明白,而且我很震惊,IE还没有解决它。
请确保您没有这样的角色!