即使表单令牌匹配会话变量令牌 - MVC,CSRF表单验证也会触发

时间:2017-12-28 20:43:42

标签: php

我有一个为表单标记生成值的函数。那是视图中隐藏的字段:

<form action="<?php echo URLROOT; ?>/users/" method="post">
    <input class="form-email" type="email" placeholder="Email Address" name="email" autocomplete="off" value="<?php echo $data['email']; ?>">
    <input class="form-password" type="password" placeholder="Password" name="password">
    <input class="login-btn btn-filled" id="login" type="submit" value="Login">
    <input type="hidden" name="form_token" id="form_token" value="<?php echo make_form_token(); ?>">
</form>

在我的控制器中我有:

public function index() 

    {

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

            $email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
            $password = trim($_POST['password']);

                $data = [

                    'email' => $email,
                    'password' => $password,
                    'message' => ''

                ];

                if(!isset($_SESSION['token']) || $_POST['form_token'] !== $_SESSION['token']) {

                    $data['message'] .= "CSRF token invalid <br />";
                }

                              // other form validation here

                           if(!empty($data['message'])) {

                    $this->view('users/index', $data);

                } else {

// success

如果我回显会话变量并查看页面源,我可以看到令牌的隐藏变量值与会话变量值完全相同。为什么然后我不断收到我的错误消息,指出CSRF令牌无效?

奇怪的是,我在网站的另一个区域做了完全相同的事情并且工作得很好。很困惑......

我也知道会话已设置,因为如果我将验证更改为:

if(!isset($_SESSION['token'])) {

然后错误就消失了。因此,它与隐藏的字段表单标记有关。

以下是创建令牌的函数:

function make_form_token() {

        $token = base64_encode(openssl_random_pseudo_bytes(32));
        $_SESSION['token'] = $token;
        return $token;

} 

0 个答案:

没有答案