【问题标题】:PHP session variable does not survivePHP会话变量不存在
【发布时间】:2017-09-22 23:54:15
【问题描述】:

非常简单的设置:当页面加载时,会生成一个随机会话令牌并保存在 $_SESSION["token"] 中。表单在隐藏的输入字段中包含此标记。到目前为止没有问题。我将表单提交到同一个页面(action=""),然后尝试检查 $_SESSION["token"] 是否等于通过 POST 发送的令牌。相应地更改了一个变量,然后我生成一个新的会话令牌,在页面再次加载之前替换旧的 $_SESSION["token"]。

问题是:在调用页面的那一刻,$_SESSION["token"] 再次更改(在我可以比较 SESSION 和 POST 令牌之前)因此,两个令牌永远不会匹配。而且我无法弄清楚它为什么会改变。这不是我写的代码行,因为这些代码也被执行了,在页面加载之前再次替换了未知来源的随机标记。

索引:

<?php
session_start();
date_default_timezone_set("Europe/Berlin");

$BASE_URL = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];

$form_valid = false;


if (isset($_POST["token"]) && isset($_SESSION["token"])) {
    if ($_POST["token"] == $_SESSION["token"]) {
        $form_valid = true;
    }
}

//Set (new) session token
$token = bin2hex(random_bytes(10));
$_SESSION["token"] = $token;

//Load actual page
include ("/backend/admin.php");
?>

包含的页面:

 <?php echo "FORM VALID:"; var_dump($form_valid); ?> 
 <?php if (!isset($_SESSION["admin"]) || !$_SESSION["admin"]) { ?>

    <form id="verify" method="POST" action="">
        <label>Password</label>
        <input type="password" name="access">
        <input type="hidden" name="token" value="<?= $_SESSION['token'] ?>">
        <input type="submit" value="Senden">
    </form>

<?php } else { ?>

    ...

<?php } ?>

感谢任何帮助。谢谢。

【问题讨论】:

    标签: php forms session token


    【解决方案1】:

    你的逻辑有问题,会话令牌每次更新都不管表单提交是不是,

    $token = bin2hex(random_bytes(10));
    $_SESSION["token"] = $token
    

    试试这个,

     <?php
        session_start();
        date_default_timezone_set("Europe/Berlin");
    
        $BASE_URL = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
    
        $form_valid = false;
    
    
    if(empty($_SESSION["token"] )){
     $_SESSION["token"]= bin2hex(random_bytes(10));
    }
    
        if (isset($_POST["token"]) && isset($_SESSION["token"]))
     {
            if ($_POST["token"] == $_SESSION["token"]) {
                $form_valid = true;
                unset($_SESSION["token"]);
            }
        }
    
    
    
    
    
        include ("/backend/admin.php");
        ?>
    

    【讨论】:

    • 好的,所以我尝试了这个,它以某种方式起作用。说是因为虽然它确实解决了问题,但它使用户无法输入错误的密码,然后再试一次。因为无论密码是什么,令牌都会被取消设置,我必须重新加载才能获得新的令牌。啊,在我上面的例子中,我剪掉了我实际检查密码正确的部分,对不起。 [1/2]
    • 但是,我仍然不明白为什么我的逻辑有缺陷。每次加载页面时获取一个新令牌应该是绝对可以的,只要在比较现有令牌之后设置新令牌或其他什么。这正是我正在做的,不是吗?当它只是一个页面重新加载时 -> 谁在乎?没有比较代币,你会得到一个新的代币。我看不出这是哪里有缺陷。但如果是的话,请赐教:/ [2/2]
    • 问题是 $_POST["token"] -> old token , $_SESSION["token"] -> new token ,因为一旦用户点击提交,页面将被刷新,SESSION 将再次更新,让 POST 保留旧令牌。希望这会有所帮助
    • 但我比较了 之前 $_SESSION["token"] 被更新/替换。页面加载 -> 比较 -> 新令牌。你是在告诉我代码不是按照写下来的顺序执行的吗?
    • 尝试从令牌输入字段中删除隐藏,并分别回显SESSION['token'],您将了解流程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    相关资源
    最近更新 更多