【问题标题】:Session variable changes value when form is submitted.提交表单时,会话变量会更改值。
【发布时间】:2016-09-16 12:04:12
【问题描述】:

我正在尝试将 CSRF 令牌添加到我的表单中。问题是当我将它添加到文件中时,我会回显会话令牌,它与名为“令牌”的输入中的令牌匹配。但是当我提交页面并使用 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;
    }
}
}
?>

这里是控制表单的php。

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

以下是处理令牌的表单部分:

<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>

如果有人能对此有所了解,我将不胜感激,因为我已经在网上搜索了几个小时,但找不到答案。谢谢。

【问题讨论】:

  • 根据您的示例代码和解释,我没有发现任何问题。正在发生的其他事情尚未提供,这使它成为一个完整的猜谜游戏。

标签: php forms session csrf


【解决方案1】:

在对代码进行了一些挖掘之后。我发现这些文件添加到网站的顺序意味着生成令牌的代码位于表单的控制器之上。因此,当表单发布时,它每次都会创建一个新的会话变量,因此发布的数据与存储在会话变量中的数据不同。更改包含这些文件的顺序解决了该问题。希望这可以帮助将来的人。

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题。在花了很多时间和调试之后,我得出了一个奇怪的解决方案。问题出在元标记上。让我告诉你我是如何解决我的问题的。

    文件名: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;
                }
            }
        }
    ?>
    

    文件名: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'; ?>
    

    文件名: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>
    

    这些是我得到的值:

    首页加载:

    // 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
    

    页面刷新后:

    // 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
    

    在令牌检查时,它会在 $_SESSION['token'] 中获得一个新的令牌值。这就是为什么它与隐藏输入框中的值不匹配的原因。调试后我发现如果我们从 header.php 中删除这一行,它就可以工作。 对此有什么有效的解释吗?

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

    或为图标使用有效的 URL,例如:

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

    结果是:

    首页加载:

    // 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
    

    页面刷新后:

    // 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
    

    【讨论】:

      猜你喜欢
      • 2016-08-18
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      相关资源
      最近更新 更多