views:

707

answers:

3

Greetings,

I am setting up a pretty standard registration form with password field.

The problem is, after a failed submission (due to empty field, incorrect format etc), the controller reloads the registration page, but with the password field containing the hashed value of the previously entered password. How do I make it empty after each failed submission?

View:

echo $form->password('Vendor.password', array('class' => 'text-input'));

Controller:

Security::setHash('sha1');
$this->Auth->sessionKey = 'Member'; 
$this->Auth->fields = array(
    'username' => 'email',
    'password' => 'password'
);

Help is very much appreciated, thanks!

+3  A: 

this?

password('Vendor.password', array('class' => 'text-input','value'=>''))
Funky Dude
Thank's, this one works too. Is this the standard way of achieving what I want?
andreas
that's how you set the value of an input field for form helper
Funky Dude
+2  A: 

In your controller:

function beforeRender() {
    parent::beforeRender();
    $this->data['Vendor']['password'] = '';
}
Matt Curry
hmmm, this seems a bit hacky to me, as I have several types of user with distinct properties in the db and could add more in the future. But for now it works I guess, thank's :)
andreas
+3  A: 

Hello, You may run into another problem down the road with cakePHP password validation.

The problem is that cake hashes passwords first, then does validation, which can cause the input to fail even if it is valid according to your rules. This is why the password is returned to the input field hashed instead of normal.


to fix this, instead of using the special field name 'password', use a different name like 'tmp_pass'. This way, cakePHP Auth won't automatically hash the field.

Here's a sample form

echo $form->create('Vendor', array('action' => 'register'));
echo $form->input('email');
echo $form->input( 'tmp_pass', array( 'label' => 'Password','type'=>'password' ));
echo $form->end('Register');


In your Vendor model, don't assign validation rules to 'password' instead assign these rules to 'tmp_pass', for example

var $validate = array('email' => 'email', 'password' => ... password rules... );

becomes

var $validate = array('email' => 'email', 'tmp_pass' => ... password rules... );


Finally, in your Vendor model, implement beforeSave().

First, see if the data validates ('tmp_pass' will be validated against your rules).

If successful, manually hash tmp_pass and put it in $this->data['Vendor']['password'] then return true. If unsuccessful, return false.

function beforeSave() {
    if($this->validates()){
        $this->data['Vendor']['password'] = sha1(Configure::read('Security.salt') . $this->data['User']['tmp_pass']);
        return true;
    }
    else
        return false;
}
smchacko
+1 - this was very helpful for me too, however I'd suggest using the proper `Auth->password()` or `Auth->hashPasswords()` functions rather than salting and hashing yourself.
nickf
You should **not** hash the password yourself with `sha1`, as this **may** introduce inconsistencies with the way `Auth` (if that's what you're using) hashes the password down the road. Use `$this->Auth->password()` instead!
deceze
@deceze, looking at the source, `Auth::hashPasswords()` will call the `User::hashPassword()` function if it is defined, whereas `Auth::password()` doesn't.
nickf
@nickf Interesting. The manual does recommend `Auth::password()` to compare a hashed and a clear password. This issue should be worth some investigation. Either one's better than `sha1` though. :)
deceze