0
votes

I am using Symfony 1.4 forms for a simple login module. The form, pretty basic has it's code listed below:

<?php 

class LoginForm extends sfFormSymfony 
{
 public function configure()
 {
  $this->setWidgets( 
         array('username' => new sfWidgetFormInputText(),
               'password' => new sfWidgetFormInputPassword(),));
              // 'remember_me' => new sfWidgetFormSelectCheckbox(array('choices'=>array('true'=>''))),));

   $this->widgetSchema->setNameFormat('login[%s]');
   $this->setValidators(array(
         'username' =>  new sfValidatorString(array('required'=>true)),        
         'password' =>  new sfValidatorString(array('required'=>true)),
     ));
 }

}

The form renders fine in the template page as expected. FYI, I use $form['username']->render method to individually render the methods where I like them instead of echoing the form out.

Upon post (recognized) I bind values to the form like this:

$this->form->bind($request->getParameter('login')); 

However, it fails against the condition

$this->form->isValid();

Both the fields are not being left empty and the credentials are correct, so this seems something more insidious to me.

Upon doing a var_dump($this->form->getValues()); it returns an empty array which I believe implies that the values were not retrieve nor bound.

Can anybody spot where I possibly am messing up ?

Thanks

3
If you dump $request->getParameter('login'), do you get the expected values?Maerlyn
yep, just did that and it dumped the username and password values as it should haveuser1020069
Did you also get the csrf token?Maerlyn
nope there was no csrf token dumpeduser1020069
That's why your form is invalid (if you have csrf protection enabled). Make sure to render the field via $form->renderHiddenFields() or $form["_csrf_token"]->render() in your template.Maerlyn

3 Answers

2
votes

As of symfony 1.3, csrf protection is enabled by default. This means that all your forms get a csrf token field, named _csrf_token by default - it's a hidden field that's unique to your session and the given form type.

If you don't render and submit this field with the rest of your form it will be invalid - it detects a csrf attack, so it's good this way.

The short fix is to render the token field:

echo $form["_csrf_token"]->render();

But the better way is to render all hidden fields in one go (I usually did this next to the submit button):

echo $form->renderHiddenFields();
1
votes

If you really need to, you can use a little snippet to display errors like this:

foreach ($this->getErrorSchema() as $field => $error) {

    if ($error instanceof sfValidatorErrorSchema) {
        foreach ($error as $field => $error) break;
    }

    echo $field . ' => ' . $error; // e.g. "Field name" => "Error message".

}
0
votes

@Maerlyn resolved this. For future reference:

The form fields were being rendered individually instead of using vanilla echo $form. Because of this, I did not render $form['_csrf_token']->render() which should have been done. Due to which the login failed. Render the csrf_token field as well and you are good to go.