首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >_token出现在POST数据上,但表单出现错误:“CSRF令牌无效。请尝试重新提交表单。”

_token出现在POST数据上,但表单出现错误:“CSRF令牌无效。请尝试重新提交表单。”
EN

Stack Overflow用户
提问于 2017-03-06 20:11:36
回答 1查看 663关注 0票数 0

我知道这个话题已经被讨论过好几次了,但是我已经检查了大量的主题,没有一个看起来像我的,到目前为止,我的测试还没有解决我的问题。第一件事是在PHP7.1.2中使用Symfony 3.2.4。

我的控制器中有以下代码:

代码语言:javascript
运行
复制
class QuoteController extends Controller
{
    /**
     * @Route("/quote/register")
     */
    public function registerAction()
    {
        $entity = new Quote();
        $form   = $this->createForm(QuoteType::class, $entity);

        return $this->render(
            'QuoteBundle:Quote:register.html.twig',
            ['entity' => $entity, 'form' => $form->createView()]
        );
    }

    /**
     * @Route("/quote/save", name="save-quote")
     */
    public function saveAction()
    {
        $entity = new Quote();
        $form   = $this->createForm(QuoteType::class, $entity);

        $request = Request::createFromGlobals();
        $form->handleRequest($request);

        if ($form->isValid()) {
            dump($form->getData());
        } else {
            dump($_POST);
            dump($form->getErrors());
        }

        die();
    }
}

这就是我的QuoteType的样子:

代码语言:javascript
运行
复制
class QuoteType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array                $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('schneider_quote_id')
            ->add('agreement_number')
            ->add('quote_creation_source')
            ->add('quote_status')
            ->add('distributor_id')
            ->add('start_date', DateType::class)
            ->add('end_date', DateType::class)
            ->add('save', SubmitType::class, ['label' => 'Create Post']);
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Quote::class,
        ]);
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'quote';
    }
}

最后,我的模板寄存器是这样的:

代码语言:javascript
运行
复制
{% block body %}
    {{ form_start(form, {'action': path('save-quote'), 'method': 'POST'}) }}
    {{ form_errors(form) }}
    {{ form_widget(form) }}
    {{ form_row(form._token) }}
    {{ form_end(form) }}
{% endblock %}

但是,当我发送表单时,我得到了错误:

CSRF令牌无效。请尽量重新提交表格。

如果您注意到,我已经在表单错误中dump()$_POST数据,这就是结果:

代码语言:javascript
运行
复制
dump($_POST);
array:1 [▼
  "quote" => array:9 [▼
    "schneider_quote_id" => "100"
    "agreement_number" => "100"
    "quote_creation_source" => "sdasdasd"
    "quote_status" => "sadsad"
    "distributor_id" => "2"
    "start_date" => array:3 [▶]
    "end_date" => array:3 [▶]
    "save" => ""
    "_token" => "bSuU7h7rDR-_FkEGZ3zS60OtIofs_1bAi-J-YdCtxlM"
  ]
]

dump($form->getErrors());
FormErrorIterator {#32 ▼
  -form: Form {#672 ▼
    -config: FormBuilder {#673 ▶}
    -parent: null
    -children: OrderedHashMap {#674 ▶}
    -errors: array:1 [▼
      0 => FormError {#625 ▶}
    ]
    -submitted: true
    -clickedButton: SubmitButton {#787 ▶}
    -modelData: Quote {#444 ▶}
    -normData: Quote {#444 ▶}
    -viewData: Quote {#444 ▶}
    -extraData: []
    -transformationFailure: null
    -defaultDataSet: true
    -lockSetData: false
  }
  -errors: array:1 [▼
    0 => FormError {#625 ▼
      -message: "The CSRF token is invalid. Please try to resubmit the form."
      #messageTemplate: "The CSRF token is invalid. Please try to resubmit the form."
      #messageParameters: []
      #messagePluralization: null
      -cause: null
      -origin: Form {#672}
    }
  ]
}

问题是,如果_token出现在POST数据上,为什么Symfony没有正确地读取这些数据?

我从表单组件上读过表单组件的文档,现在我很困惑,也许Symfony 3中的事情已经改变了,我不知道。在某种程度上,我需要控制器表格中的代码吗?

代码语言:javascript
运行
复制
use Symfony\Component\Form\Forms;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage;
use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
use Symfony\Component\Security\Csrf\CsrfTokenManager;

// create a Session object from the HttpFoundation component
$session = new Session();

$csrfGenerator = new UriSafeTokenGenerator();
$csrfStorage = new SessionTokenStorage($session);
$csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);

$formFactory = Forms::createFormFactoryBuilder()
    // ...
    ->addExtension(new CsrfExtension($csrfManager))
    ->getFormFactory();

我为什么要在这里失踪?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-07 15:14:16

经过几次头痛之后,我终于找到了问题的根源。这就是我的session部分在config.yml上的样子

代码语言:javascript
运行
复制
session:
    storage_id: session.storage.php_bridge
    handler_id: ~
    save_path:  ~

将上述配置更改为此配置:

代码语言:javascript
运行
复制
session:
    handler_id: session.handler.native_file
    save_path:  ~

因此,显然~根本没有设置默认的handler_id

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42634679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档