Symfony2表单构建器可以用于登录表单吗? [英] Can the Symfony2 form builder be used for the login form?

查看:114
本文介绍了Symfony2表单构建器可以用于登录表单吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了最后几个小时来尝试使用Symfony表单构建器构建一个登录表单.

I have spent the last several hours trying to get a login form built with the Symfony form builder to work.

据我所知,问题在于表单构建器创建了formName [fieldName]形式的字段名称(例如,login [_username]),并且安全组件正在寻找平面"字段名称(例如,_username) ).这会导致CSRF提交失败.

As far as I can tell, the problem is that the form builder creates field names of the form formName[fieldName] (e.g., login[_username]) and the security component looks for "flat" field names (e.g., _username). This results in a CSRF failure on submit.

我一直无法找到任何方法来迫使表单生成器生成平面字段名称.

I have been unable to find any way to coerce the form builder into producing flat field names.

有人知道使用表单生成器构建登录表单的方法吗? 甚至有可能吗?

Does anyone know of a way to use the form builder to build the login form? Is it even possible?

谢谢.

------------更新以回应Cerad的回答-------------------

------------ Update in response to Cerad's answer -------------------

Cerad.感谢您的答复和链接.

Cerad. Thanks for the reply and the link.

我已将我的security.yml更新为:

I've updated my security.yml to this:

    firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        main:
            pattern: ^/
            provider:
            form_login:
                check_path:                     userLoginCheck
                login_path:                     userLogin
                always_use_default_target_path: true
                default_target_path:            /
                username_parameter:             login[email]
                password_parameter:             login[password]
                csrf_parameter:                 login[_token]
                intention:                      authenticate
                csrf_provider:                  form.csrf_provider
            logout:         true
            anonymous:      true
            switch_user:    { role: ROLE_SUPER_ADMIN }

我呈现的表单与您的示例略有不同.
我正在使用表单类型,并在控制器中调用$ this-> createForm().
呈现的表单如下所示:

I'm rendering the form a little differently than in your example.
I'm using a form type and calling $this->createForm() in my controller.
The rendered form looks like this:

<form name="login"
      method="post"
      action="/user/loginCheck"
      class="dplhUser"
      novalidate="novalidate">
  <div id="login">
    <div class="formRow">
      <label for="login_email"
             class="required">Email:</label>
      <input type="text"
             id="login_email"
             name="login[email]"
             required="required"/>
    </div>
    <div class="formRow">
      <label for="login_password"
             class="required">Password:</label>
      <input type="password"
             id="login_password"
             name="login[password]"
             required="required"/>
    </div>
    <input type="hidden"
           id="login__token"
           name="login[_token]"
           value="ij3CcnLiHzeLrNUDnxXtdExcPvGkgusIEriYmnZmgy8"/></div>
  <label for="submit"></label>
  <input type="submit"
         name="submit"
         Value="Login"/>
</form>

name属性与security.yml中的属性匹配.
我清除了缓存并删除了会话cookie.仍然出现CSRF故障.

The name attributes match those that are now in security.yml.
I Cleared the cache and deleted the session cookie. Still getting CSRF failures.

表单构造:

class LoginType extends AbstractType
{
  public function buildForm( FormBuilderInterface $builder, array $options )
  {
    $builder
      ->add( 'email', null, ['mapped' => false] )
      ->add( 'password', 'password', ['mapped' => false] );
  }
  public function getName()
  {
    return 'login';
  }
  public function setDefaultOptions( OptionsResolverInterface $resolver )
  {
    $resolver->setDefaults( ['intention' => 'authentication'] );
  }
}

推荐答案

我认为您很亲密,但没有更改表单字段名称,而是更改了安全系统期望的名称.大部分内容都在参考部分中进行了记录,但是将它们放在一起确实需要一些时间.

I think you were close but instead of trying to change the form field names, you change the names that the security system are expecting. Most of this is documented in the reference section but it does take a bit to put it all together.

http://symfony.com/doc/current/reference/configuration/security.html

        # security.yml
        form_login:
            provider:            cerad_tourn_account_user_provider
            login_path:          cerad_tourn_account_user_login
            check_path:          cerad_tourn_account_user_login_check
            default_target_path: cerad_tourn_home

            # This matches your form element names
            username_parameter:  cerad_tourn_account_user_login[username]
            password_parameter:  cerad_tourn_account_user_login[password]
            csrf_parameter:      cerad_tourn_account_user_login[_token]
            csrf_provider:       form.csrf_provider
            intention:           authenticate

protected function createFormForModel($model)
{        
    /* ======================================================
     * Start building
     */
    $formOptions = array(
        'cascade_validation' => true,
        'intention' => 'authenticate', // Matches security.yml
        'csrf_protection' => true,
    );
    $constraintOptions = array();

    // The name here matches your security file
    $builder = $this->get('form.factory')->createNamed(
        'cerad_tourn_account_user_login',
        'form',$model,$formOptions);

    $builder->add('username','text', array(
        'required' => true,
        'label'    => 'Email',
        'trim'     => true,
        'constraints' => array(
            new UsernameOrEmailExistsConstraint($constraintOptions),
        ),
        'attr' => array('size' => 30),
     ));
     $builder->add('password','password', array(
        'required' => true,
        'label'    => 'Password',
        'trim'     => true,
        'constraints' => array(
            new NotBlankConstraint($constraintOptions),
        ),
        'attr' => array('size' => 30),
    ));
    $builder->add('remember_me','checkbox',  array('label' => 'Remember Me'));

    // Actually a form
    return $builder;
}

模板没什么特别的,form_rest(form)将输出csrf _token.

Nothing special about the template, the form_rest(form) will output the csrf _token.

这篇关于Symfony2表单构建器可以用于登录表单吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆