【问题标题】:Is it possible to handle a plain old HTML form with Symfony, but with CSRF token?是否可以使用 Symfony 处理普通的旧 HTML 表单,但使用 CSRF 令牌?
【发布时间】:2019-03-30 01:18:31
【问题描述】:

我正在为我的应用制作 Bootstrap 4 风格的付款表单,其中单选按钮选择付款方式。在尝试通过 Symfony 的表单类制作我的表单时,我发现它们过于严格/笨拙,无法做我想做的事。我不想搞乱 Symfony 表单主题(我觉得它很冗长),我不想使用 Symfony 的预制 Bootstrap 主题,我不想使用任何 createFormBuilder 任何东西。

那么,有没有办法让我制作一个普通的旧 HTML 表单,但使用 Symfony 的 CSRF 令牌?这个answer 看起来很有希望,但没有提到 CSRF 保护。

【问题讨论】:

标签: php forms symfony


【解决方案1】:

根据本文档 How to Implement CSRF Protection , 解决方案的尝试是使用类似的东西(在 symfony 3.4 和 4 中):

  • 在您的控制器中,您可以使用以下内容:
   /**
     * @Route("/names", methods={"POST"}, name="app_post_names")
     */
    public function postName(Request $request)
    {
        $name = $request->request->get('name');
        $csrfToken = $request->request->get('_csrf_token');

         if(!$this->isCsrfTokenValid('token_id', $csrfToken)) {
          // ... throw bad request
         } 

         // ... Do other thing
    }

  • 现在在您的模板中,您可以使用类似的内容(使用您自己的设计):
<form action="{{ path('app_post_names') }}" method="post">
    Name : <input name="name" type="text" />
    <input name="_csrf_token" value="{{ csrf_token('token_id') }}" type="hidden" />
    <input type="submit" value="send" />
</form>

【讨论】:

    【解决方案2】:

    根本不使用 Symfony,并生成自己的令牌?

    在制作表单时,您实际上并不需要使用 Symfony 表单主题。我自己,我总是建立自己的表单标签。

    • 您想自定义您的选择吗?也可以做
    • 您想使用不在实体中的字段,也可以这样做...

    Symfony 表单并没有你想象的那么严格。

    你很可能不知道这件事的“诀窍”。

    控制器

    public function customFormAction(Request $request) {
        $form=$this->createFormBuilder()
                   ->setAction($this->generateUrl('route_name'))
                   ->setMethod('POST')
                   ->add("customField", ChoiceType::class, array(
                       'choices'=>array(
                           '1'=>'Choice 1',
                           '2'=>'Choice 2',
                           '3'=>'Choice 2',
                       ),
                       'required'=>true,
                       'mapped'=>false, //Isn't mapped to any entity
                   ))
                   ->getForm();
    
        $form->handleRequest($request);
        if($form->isSubmitted() && $form->isValid()) {
            $customField=$form->get('customField')->getData();
            //do your stuff
        }
    
        return $this->render('route_name', array(
            'form'=>$form->createView(),
        ));
    }
    

    树枝视图

    <form action="{{ form.vars.action }}" method="{{ form.vars.method }}">
        <div class="input-field">
            <select id="{{ form.customField.vars.id }}" name="{{ form.customField.vars.full_name }}" class="my_classes">
                {% for option in form.customField.vars.choices %}
                    <option data-attr="my_attributes" value="{{ option.value }}">{{ option.label }}</option>
                {% endfor %}
            </select>
        </div>
        <input name="{{ form._token.vars.full_name }}" value="{{ form._token.vars.value }}" type="hidden">
    </form>
    

    有了这个,我几乎不使用任何树枝模板,我仍然有一个 CSRF 令牌,Symfony 几乎不处理表单(它只会检查 CSRF 令牌)

    【讨论】:

      猜你喜欢
      • 2013-12-02
      • 2018-07-17
      • 2012-08-15
      • 1970-01-01
      • 2017-11-20
      • 2017-02-10
      • 2020-08-08
      • 2013-04-14
      • 2013-04-12
      相关资源
      最近更新 更多