yii2 无法验证您提交的数据

pup*_*upa 6 session csrf yii yii2

我使用 nginx、PHP 5.5.14、php-fpm、yii2、mac os。

我更改了 yii 配置以将会话存储在数据库中(postgress,用户是超级用户)。这是在我的配置中:

  'session' => [
        'class' => 'yii\web\DbSession',
        'sessionTable' => 'session',
    ],
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试注册新用户时,出现此错误:

Bad Request (#400)
Unable to verify your data submission
Run Code Online (Sandbox Code Playgroud)

这是日志的一部分:

10  17:25:57.434    info    yii\db\Command::query   SELECT "data" FROM "session" WHERE "expire">1425993957 AND "id"='cfg9sutufqchr1tdose4cack15'
/Users/pupadupa/Dev/www/mint-office-web/components/Controller.php (41)
11  17:25:57.442    info    yii\web\Session::open   Session started
/Users/pupadupa/Dev/www/mint-office-web/components/Controller.php (41)
12  17:25:57.450    error   yii\web\HttpException:400   exception 'yii\web\BadRequestHttpException' with message '?? ??????? ????????? ?????????? ??????.' in /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/web/Controller.php:110
Stack trace:
#0 /Users/pupadupa/Dev/www/mint-office-web/components/Controller.php(41): yii\web\Controller->beforeAction(Object(app\controllers\user\RegistrationAction))
#1 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/base/Controller.php(149): app\components\Controller->beforeAction(Object(app\controllers\user\RegistrationAction))
#2 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/base/Module.php(455): yii\base\Controller->runAction('registration', Array)
#3 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/web/Application.php(83): yii\base\Module->runAction('user/registrati...', Array)
#4 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/base/Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))
#5 /Users/pupadupa/Dev/www/mint-office-web/web/index.php(20): yii\base\Application->run()
#6 {main}
13  17:25:57.454    trace   yii\base\Controller::runAction  Route to run: index/error
Run Code Online (Sandbox Code Playgroud)

顺便提一句,

  1. 我进入<?= Html::csrfMetaTags() ?>了头部,我的表单中有 csrf 输入。所以这似乎不是问题
  2. 我不想这样做,public $enableCsrfValidation = false;因为我认为这不是解决方案,而是解决方法。

我怎么能理解是什么导致了这个错误? 正如我之前提到的,只有当我将会话存储在数据库中时才会出现问题。


一些附加信息:我可以从会话中设置和获取变量。例如,我把它beoreActionController.php

Yii::$app->session->set('test', 'qwe');
$t = Yii::$app->session->get('test') ;
var_dump($t);
Run Code Online (Sandbox Code Playgroud)

但在那之后如果我像这样评论第一行

//Yii::$app->session->set('test', 'qwe');
$t = Yii::$app->session->get('test') ;
var_dump($t);
Run Code Online (Sandbox Code Playgroud)

并刷新页面 - 我收到 NULL(顺便说一句Cookie:PHPSESSID=cfg9sutufqchr1tdose4cack15,刷新后我可以在 cookie 中看到)。

因此,会话(DbSession)或我的 php/php-fpm/nginx 设置似乎存在一些问题。


我的UserController.php

<?php

namespace app\controllers;


use app\components\Controller;
use app\models\Client;
use app\models\User;
use yii\filters\AccessControl;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;

class UserController extends Controller
{

    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['logout', 'employee'],
                'rules' => [
                    [
                        'actions' => ['logout',],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                    [
                        'actions' => ['employee', 'employee_add'],
                        'allow' => true,
                        'roles' => [ROLE_CLIENT_ADMIN],
                    ],
                ],

            ],
        ];
    }

    public function actions()
    {
        return [
            'login' => 'app\controllers\user\LoginAction',
            'logout' => 'app\controllers\user\LogoutAction',
            'restore' => 'app\controllers\user\RestoreAction',
            'registration' => 'app\controllers\user\RegistrationAction',
            'employee' => 'app\controllers\user\EmployeeAction',
            'employee_add' => 'app\controllers\user\EmployeeAddAction',
            //'passwd' => 'app\controllers\user\PasswdAction',
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV === 'dev' ? 'testme' : null,
            ],
        ];
    }

    /**
     * @param int $clientId
     * @return Client
     * @throws BadRequestHttpException
     * @throws NotFoundHttpException
     */
    public function getClient($clientId)
    {
        if (!\Yii::$app->user->can(ROLE_ADMIN)) {
            /* @var User $user */
            $user = \Yii::$app->user->identity;
            $clientId = $user->client_id;
        }
        if (!$clientId) {
            throw new BadRequestHttpException('Bad request');
        }

        $client = Client::find()->where(['id' => $clientId])->one();
        if (!$client) {
            throw new NotFoundHttpException('???????? ?? ???????');
        }

        return $client;
    }

} 
Run Code Online (Sandbox Code Playgroud)

我的RegistrationAction.php

<?php
namespace app\controllers\user;


use app\models\UserConfirm;
use Yii;
use app\components\Action;
use app\forms\RegistrationForm;
use yii\web\NotFoundHttpException;

class RegistrationAction extends Action
{

    public function run($key = null)
    {
        if ($key !== null) {
            /* @var UserConfirm $confirm */
            $confirm = UserConfirm::find()->andWhere('expire > NOW()')->andWhere([
                    'key' => $key,
                    'action' => 'reg'
                ])->one();
            if (!$confirm) {
                throw new NotFoundHttpException('Key not found');
            }

            $user = $confirm->user;
            $user->enabled = true;
            $user->last_login = date('Y-m-d H:i:s');
            $user->save();

            $confirm->delete();

            Yii::$app->user->login($user, 0);
            return $this->controller->goHome();
        }

        $model = new RegistrationForm();
        if ($model->load($_POST) && $model->validate() && $model->register()) {

            $subject = Yii::$app->name . ' - Success';
            $message = $this->controller->renderPartial(
                '//email/registration',
                [
                    'username' => $model->email,
                    'password' => $model->password,
                    'key' => $model->key,
                    'keyExpire' => $model->keyExpire
                ]
            );

            $res = Yii::$app->mailer->compose()
                ->setTo($model->email)
                ->setFrom([Yii::$app->params['from'] => Yii::$app->params['fromName']])
                ->setSubject($subject)
                ->setHtmlBody($message)
                ->send();

            Yii::$app->session->setFlash('registrationFormSubmitted');
            return $this->controller->refresh();
        }

        return $this->controller->render('registration', ['model' => $model]);
    }

}
Run Code Online (Sandbox Code Playgroud)

小智 1

您的会话 ID 似乎已更改。检查会话 cookie 的值在第二次请求后是否发生变化。当您错误配置为会话 cookie 设置的域时,会发生这种情况,请确保它与 URL 中的主机名匹配。