2013-04-24 04:13 阅读 17

CakePHP - 密码确认不允许用户提交注册

I'm trying to set up validation for user registration but I'm having troubles. When I only have the email,role and password fields in the $validation array (remove the others) it works and will save a new user. When I try to add the other fields it fails and gives the flash message error "The user could not be saved. Please, try again."

I'm pretty sure it's the re_password check. When I remove the validation for that it works. However, the re_password validation does display an error when the passwords are different, so I'm not sure where to look

Here's my users table

id  |  email  |  password  |  location  | website  | role  | created |  modified

Here's the validation requirements. To get it to save a new user I have to remove everything but email, password and role.

public $validate = array(
    'email' => 'email'
    'password' => array(
        'required' => array(
            'rule' => array('minLength', '8'),
            'message' => 'A password with a minimum length of 8 characters is required'
    're_password' => array(
        'required' => array(
            'rule' => array('equalTo', 'password' ), 
            'message' => 'Both password fields must be filled out'
    'role' => array(
        'valid' => array(
            'rule' => array('inList', array('admin', 'author')),
            'message' => 'Please enter a valid role',
            'allowEmpty' => false
     'location' => array(
        'valid' => array(
            'rule' => array('notEmpty'),
            'message' => 'Please select a location'

Here's the form (the options array is above, figured it's not necessary to show)

    echo $this->Form->input('email');
    echo $this->Form->input('password');
    echo $this->Form->input('re_password', array('type'=>'password', 'label'=>'Re-Enter Password', 'value'=>'', 'autocomplete'=>'off'));
    echo $this->Form->input('location', array('options' => $options, 'label' => 'Select Nearest Location'));
    echo $this->Form->input('website',array('label'=>'Enter your website, such as www.example.com. ')); 
    echo $this->Form->input('role', array('type' => 'hidden', 'default' => 'user'));

Here's the re_password checking function in the User model

function check_user_password($userid) { 
    $salt = Configure::read('Security.salt');
    $this->User->id = $userid;
    $hashed_password = $this->User->field('password');
    // check password  
    if($hashed_password == md5($data['User']['re_password'].$salt)) {  
        return true;
    } else {
        return false;

And finally, here's the add function in UsersController

public function add() {  
        if ($this->request->is('post')) {  
            $this->User->create();     //create initiates a form on User/add.ctp
            if ($this->User->save($this->request->data)) {  //save the form data
                $this->Session->setFlash(__('The user has been saved'));
                $this->redirect(array('controller' => 'demos', 'action' => 'index'));
            } else {
                $this->Session->setFlash(__('The user could not be saved. Please, try again.'));

Please let me know if there's anything else you need to see

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

3条回答 默认 最新

  • 已采纳
    dsklzerpx64815631 dsklzerpx64815631 2013-04-24 08:31

    I believe that your re_passwords valiadtion rule equalTo compares its value to string password and not the actual field. I like to use custom functions for this.

    so try replacing re_passwords rule array

     //'rule' => array('equalTo', 'password' ),
    'rule' => array('equalToField', 'password'),

    and declare equalToField function in that model

    function equalToField($array, $field) {
        return strcmp($this->data[$this->alias][key($array)], $this->data[$this->alias][$field]) == 0;

    ** Also in the future when you seem to have a problem with validation rules try this in your controllers action (its faster than removing every single rule)

    if ($this->User->save($this->request->data)) {
    } else {

    I hope this helps.

    点赞 评论 复制链接分享
  • duai4379 duai4379 2013-04-24 11:16

    Hi Please use following code for your requirement :

    override equalTo function by putting your own method in user model:

    function equalTo( $field=array(), $compare_field=null ) 
        foreach( $field as $key => $value ){
            $v1 = $value;
            $v2 = $this->data[$this->name][ $compare_field ];
            if($v1 !== $v2) {
                return FALSE;
            } else {
        return TRUE;
    点赞 评论 复制链接分享
  • dongshanxun6479 dongshanxun6479 2014-01-22 11:47

    Attention, in @luboss answer, where he declares:

    function equalToField($array, $field) {
        return strcmp($this->data[$this->alias][key($array)], $this->data[$this->alias][$field]) == 0;

    That cannot work as we are comparing inconsistent fields: the left member of strcmp has already been hashed, but not the right member. This happens as a CakePHP automation because the field is called password.

    The way I got this to work was to reuse the hashing function in the equalToField helper:

    public function equalToField($array, $field) {
        $valueFirstOccurrence = $this->data[$this->alias][$field];
        $valueSecondOccurrence = Security::hash($this->data[$this->alias][key($array)], $type = 'sha1', $salt = true) ;
        return !strcmp($valueFirstOccurrence, $valueSecondOccurrence);

    Other point : If you are interested in adding a minLength validation field for your password field, you want to read this good post first: minLength data validation is not working with Auth component for CakePHP

    点赞 评论 复制链接分享