简体   繁体   English

会话变量在提交表单时更改值。

[英]Session variable changes value when form is submitted.

I am trying to add CSRF tokens to my forms. 我正在尝试将CS​​RF令牌添加到我的表单中。 The problem is when I add it in the file I echo out the session token and it matches the token in the input named 'token'. 问题是当我在文件中添加它时,我回显出会话令牌,它匹配名为'token'的输入中的令牌。 But when I submit the page and use Token::check it returns false and if I echo out the token value from the input and the session again I see that the session value has changed but the input value has stayed the same. 但是,当我提交页面并使用Token :: check时,它返回false,如果我再次从输入和会话中回显令牌值,我会看到会话值已更改但输入值保持不变。

<?php
class Token{
public static function generate(){
    return $_SESSION['token'] =    base64_encode(openssl_random_pseudo_bytes(32)); 
}

public static function check($token){
    if(isset($_SESSION['token']) && $token == $_SESSION['token']){
        unset($_SESSION['token']);
        return true;
    }else{
        return false;
    }
}
}
?>

Here is the php to control the form. 这是用来控制表单的php。

$token = $_POST['token'];
if(Token::check($token)){ //Continue with more code }

Below is a the part of the form that deals with the tokens: 以下是处理令牌的表单部分:

<input type="hidden" name="user_id_update" value="<?php echo $user_info[0][0]->id; ?>"/>
                            <input type="hidden" name="time_update" value="<?php echo $time; ?>"/>
                            <input type="hidden" name="token" value="<?php echo Token::generate(); ?>"
                            <hr />

                            <div class="form-group">
                                <input type="submit" id="submit_update" value="Update" class="btn btn-success"/>
                            </div>

If anybody can shed some light on this I'd really appreciate it as I've been searching online for hours now and can't find an answer. 如果有人能对此有所了解,我会非常感激,因为我已经在网上搜索了几个小时,但找不到答案。 Thanks. 谢谢。

After some digging through the code. 经过一些挖掘代码。 I found that the order that these files were added into the website meant that the code to generate the token was above the controllers for the form. 我发现这些文件被添加到网站的顺序意味着生成令牌的代码位于表单的控制器之上。 As such when the form was posted it created a new session variable each time and therefore the posted data was not the same as the data stored in the session variable. 因此,当表单发布时,它每次都创建一个新的会话变量,因此发布的数据与存储在会话变量中的数据不同。 Changing around the order in which these files were included solved the problem. 改变包含这些文件的顺序解决了这个问题。 Hope this can help someone out in the future. 希望这可以在将来帮助某人。

Same problem was with me also. 同样的问题也与我同在。 After spending lots of time and debugging, I came to a strange solution. 花了很多时间和调试后,我找到了一个奇怪的解决方案。 The problem was with meta tag. 问题出在meta标签上。 Let me tell you how I resolved my problem. 让我告诉你我是如何解决我的问题的。

Filename: Token.php 文件名:Token.php

<?php
    class Token
    {
        public static function generate()
        {
            return $_SESSION['token'] = md5(time() . uniqid());
        }

        public static function check($token)
        {
            if (isset($_SESSION['token']) && $token == $_SESSION['token']) {
                unset($_SESSION['token']);
                return true;
            } else {
                return false;
            }
        }
    }
?>

Filename: myscript.php 文件名:myscript.php

<?php require_once 'header.php'; ?>

<?php
     if ($_SERVER['REQUEST_METHOD'] == 'POST') {

         if(Token::check($_POST['token'])) {
              echo 'valid token';

              // code...
         } else {
              echo 'invalid token';
         }

     }
?>

<form action="" method="post">
    <!-- other fields -->
    <input type="hidden" name="token" value="<?php echo Token::generate();?>">
    <input type="submit" value="Submit">
</form>

<?php require_once 'footer.php'; ?>

Filename: header.php 文件名:header.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="author" content="Ishtiyaq Husain">
    <link rel="shortcut icon" href="#" />

    <!-- other css files -->
</head>

These are values I was getting: 这些是我得到的价值观:

First Page Load: 首页加载:

// print old token value from session
echo $_SESSION['token']; //no value
// generate new token
echo Token::generate();  // e72a2f53a25f364e8a2e62e556f7e417
// print new token value from session
echo $_SESSION['token']; // e72a2f53a25f364e8a2e62e556f7e417

After Page Refresh: 页面刷新后:

// print old token value from session
echo $_SESSION['token']; // a63e674d55e9248c25a48856649bf590 //expected value -> e72a2f53a25f364e8a2e62e556f7e417
// generate new token
echo Token::generate();  // 237063c2f7892242c79bfabcd48bcdc8
// print new token value from session
echo $_SESSION['token']; // 237063c2f7892242c79bfabcd48bcdc8

At the time of token check it gets a new token value in $_SESSION['token']. 在令牌检查时,它在$ _SESSION ['token']中获得一个新的令牌值。 Thats why it doesn't matches with the value from hidden input box. 这就是为什么它与隐藏输入框的值不匹配。 After debugging I found that if we remove this line from header.php, it works. 调试后我发现如果我们从header.php中删除这一行,它就可以了。 Is there any valid explanation for that? 对此有任何有效的解释吗?

<link rel="shortcut icon" href="#" />

or Use a valid URL for icon like: 或使用有效的URL图标,如:

<link rel="shortcut icon" href="http://ishtiyaq.com/images/iLogo.png" />

Result was: 结果是:

First Page Load: 首页加载:

// print old token value from session
echo $_SESSION['token']; //no value
// generate new token
echo Token::generate();  // 36e48f2307da7054c67822147878e0c6
// print new token value from session
echo $_SESSION['token']; // 36e48f2307da7054c67822147878e0c6

After Page Refresh: 页面刷新后:

// print old token value from session
echo $_SESSION['token']; // 36e48f2307da7054c67822147878e0c6 //as expected
// generate new token
echo Token::generate(); // 734eaeeb862d4d0d52eea1a292f007ec
// print new token value from session
echo $_SESSION['token']; // 734eaeeb862d4d0d52eea1a292f007ec

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM