【问题标题】:Keeping a generated variable after form submit on same page在同一页面上提交表单后保留生成的变量
【发布时间】:2014-09-21 19:24:15
【问题描述】:

这有点难以解释,我在注册脚本所在的页面上有一个注册表单,并且我正在通过令牌使用 CSRF 保护。生成页面时,令牌会生成到 SESSION 变量中。我有一个在提交 POST 数据以注册用户时执行的函数。提交数据后,脚本会重新生成另一个令牌,因此我无法根据会话变量检查令牌。如果我删除函数包装器,请查看下面的代码,然后一切正常。我有这个功能的原因是在某个 div 中显示错误。我所有的 PHP 类都可以正常工作,所以这不是问题,但如果您需要查看代码,请询问。

代码:

<?php
require_once "assets/php/core/init.php";
require_once "assets/php/core/autoload.php";

function register(){
    if(Input::exists()){
        if(Token::check(Input::get("token"))){
            echo 'Token Checked';
            $spamField = Input::get("automated");
            if(!isset($spamField)){
                $Validation = new Validation();
                $Validation->validate(array(
                    'username' => array(
                        'key' => 'Username',
                        'value' => Input::get("username"),
                        'min' => '1',
                        'max' => '32',
                        'alphanumeric' => true,
                        'required' => true
                    ),
                    'email' => array(
                        'key' => 'E-Mail',
                        'value' => Input::get("email"),
                        'max' => '128',
                        'email' => true,
                        'required' => true
                    ),
                    'password' => array(
                        'key' => 'Password',
                        'value' => Input::get("password"),
                        'required' => true
                    )
                ));

                if($Validation->passed()){
                    echo 'OK';
                } else {
                    foreach($Validation->errors() as $error){
                        echo $error . '<br>';
                    }
                }
            }
        }
    }
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>Codemy - Register</title>
    <link rel="stylesheet" type="text/css" href="assets/css/core/core.css">
    <link rel="stylesheet" type="text/css" href="assets/css/core/fonts.css">
    <link rel="stylesheet" type="text/css" href="assets/css/extra/fontello/css/fontello.css">
    <script type="text/javascript" src="assets/js/extra/jquery.js"></script>
    <script type="text/javascript" src="assets/js/core/core.js"></script>
</head>
<body>
<header>
    <div class="row">
        <div class="container clearfix">
            <div id="logo"><a href="./">Codemy</a></div>

            <ul class="right links">
                <li><a href="#" class="fade-in">Features</a></li>
                <li><a href="#" class="fade-in">Premium</a></li>
                <li><a href="#" class="fade-in">Explore</a></li>
                <li><a href="login.php" class="btn btn-primary btn-red fade-in toggle">Sign In</a></li>
            </ul>
        </div>
    </div>
</header>

<main>
    <section>
        <div class="row">
            <div class="box-half white-background">
                <form class="form" method="post" action="register.php">
                    <div class="form-header clearfix">
                        <div class="column half">
                            <h1 class="form-title left">Create an Account for Free</h1>
                        </div>
                        <div class="column half">
                            <p class="right form-note">Have an account? <a href="login.php" class="red
                            secondary">Click
                                    Here</a></p>
                        </div>
                    </div>

                    <div class="form-body">
                        <div class="box-two-thirds">
                            <div class="row">
                                <label form="username" class="form-label">Username:</label>
                                <input id="username" type="text" name="username" class="form-input fade-in width-full"
                                       placeholder="Username" autocomplete="off" autofocus="true">
                            </div>

                            <div class="row">
                                <label form="email" class="form-label">E-Mail:</label>
                                <input id="email" type="text" name="email" class="form-input fade-in width-full"
                                       placeholder="E-Mail" autocomplete="off">
                            </div>

                            <div class="row">
                                <label form="password" class="form-label">Password:</label>
                                <input id="password" type="password" name="password" class="form-input fade-in
                            width-full" placeholder="Password" autocomplete="off">
                            </div>

                            <div class="row">
                                <input type="submit" name="submit" class="btn btn-medium btn-primary btn-red
                            width-full fade-in" value="Get Started For Free">
                            </div>

                            <div class="row">
                                <input type="text" name="automated" class="hidden">
                                <input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
                            </div>

                            <div class="row">
                                <p><?php register(); ?></p>
                            </div>
                        </div>
                    </div>

                    <div class="form-footer">
                        <p class="form-note">By signing up, you agree to our <a href="#" class="red
                        secondary">Terms of Service</a></p>
                    </div>
                </form>
            </div>
        </div>
    </section>
</main>

<footer>
    <div class="container">
        <div class="row clearfix">
            <p class="left no-margin" style="line-height: 75px;">Built In Chicago | &copy; 2014 Codemy</p>

            <div class="right">
                <ul class="footer-links">
                    <li><a href="#">Terms</a></li>
                    <li><a href="#">Privacy Policy</a></li>
                    <li><a href="#">Help</a></li>
                    <li><a href="#">Contact</a></li>
                </ul>
            </div>
        </div>
    </div>
</footer>
</body>
</html>

【问题讨论】:

  • 这只是范围问题吗?你说如果你不将代码包装在一个函数中,这段代码就可以工作,所以它可能是。

标签: php html forms validation csrf


【解决方案1】:

我认为您需要手动记录之前生成的唯一令牌。这样您就可以对照“previousToken”检查POST,并使用新的Token 做其他事情。

可能是这样的:

$_SESSION['previousToken'] = $_SESSION['Token'];

这对您有任何帮助吗?

【讨论】:

  • 请记住,您需要在生成新 Token 之前执行此操作。您也可以在生成新 Token 后执行此操作,但您需要确保不会一直覆盖您的控制数据。
  • 是的...我真的不知道该放在哪里,您能再帮帮我吗?
  • 您能否包含或解释生成令牌的位置以及在您的应用程序中何时调用这些方法?
  • 令牌正在以下面的形式生成。生成令牌时,它将值存储在名为“令牌”的会话中,if() 语句检查保存令牌的隐藏输入值是否与会话数据匹配。
  • 如果你只是把 Token 生成之前?顺便说一下,你能解释一下为什么这么晚才将函数调用放在已经生成的表单中吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多