Internet Explorer中的PHP会话数据更改

时间:2014-03-01 14:50:12

标签: php internet-explorer session

我已经使用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}}

7 个答案:

答案 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_APPENDtime()来识别它们。第一个附加到文件(显然),因此日志条目不会相互覆盖,第二个有助于知道您的日志的两个条目是否在同一请求中。

这就是我所拥有的一切。最后,您可能希望设置日志条目的样式,使其更具可读性。

答案 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还没有解决它。

请确保您没有这样的角色!