PHP会话变量不存在

PHP会话变量不存在,php,forms,session,token,Php,Forms,Session,Token,非常简单的设置:加载页面时,会生成一个随机会话令牌并保存在$\u session[“token”]中。表单在隐藏的输入字段中包含此标记。在这之前没有问题。我将表单提交到同一页面(action=“”),然后尝试检查$\u会话[“token”]是否等于通过POST发送的token。相应地更改了一个变量,然后我生成了一个新的会话令牌,在再次加载页面之前替换旧的$u会话[“令牌”] 问题是:调用页面时,$\u会话[“令牌”]会再次更改(在我可以比较会话和POST令牌之前),因此,两个令牌永远不会匹配。我

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

问题是:调用页面时,$\u会话[“令牌”]会再次更改(在我可以比较会话和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 } ?>

密码

您的逻辑有问题,无论是否提交表单,会话令牌每次都会更新

$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]问题是$\u POST[“token”]->旧token,$\u SESSION[“token”]->新token,因为一旦用户点击submit,页面将刷新,会话将再次更新,让POST拥有旧token。希望这有帮助,但在更新/替换$u会话[“令牌”]之前,我将两者进行比较。页面加载->比较->新建令牌。你是在告诉我代码不是按照写下来的顺序执行的吗?试着从令牌输入字段中删除隐藏项,然后分别回显会话['token'],你就会了解流程。