cakephp密码验证

时间:2010-09-21 13:19:34

标签: php cakephp passwords

var $validate = array(
  'password' => array(
      'passwordlength' => array('rule' => array('between', 8, 50),'message' => 'Enter 8-50 chars'),
      'passwordequal' => array('checkpasswords','message' => 'Passwords dont match') 
  )
);

function checkpasswords()
{
   return strcmp($this->data['Airline']['password'],$this->data['Airline']['confirm password']);
}

此代码无效,即使匹配也始终显示错误消息。此外,当我进行编辑时,我得到了跟随错误,因为没有密码字段。有任何修复

Undefined index:  password [APP/models/airline.php, line 25]

6 个答案:

答案 0 :(得分:12)

您使用的是AuthComponent吗?请注意,它会散列所有传入的密码字段(但不是“密码确认”字段,请与debug($this->data)一起检查),因此字段将永远不会相同。 Read the manual and use AuthComponent::password进行检查。


话虽如此,这是我使用的东西:

public $validate = array(
    'password' => array(
        'confirm' => array(
            'rule' => array('password', 'password_control', 'confirm'),
            'message' => 'Repeat password',
            'last' => true
        ),
        'length' => array(
            'rule' => array('password', 'password_control', 'length'),
            'message' => 'At least 6 characters'
        )
    ),
    'password_control' => array(
        'notempty' => array(
            'rule' => array('notEmpty'),
            'allowEmpty' => false,
            'message' => 'Repeat password'
        )
    )
);

public function password($data, $controlField, $test) {
    if (!isset($this->data[$this->alias][$controlField])) {
        trigger_error('Password control field not set.');
        return false;
    }

    $field = key($data);
    $password = current($data);
    $controlPassword = $this->data[$this->alias][$controlField];

    switch ($test) {
        case 'confirm' :
            if ($password !== Security::hash($controlPassword, null, true)) {
                $this->invalidate($controlField, 'Repeat password');
                return false;
            }
            return true;

        case 'length' :
            return strlen($controlPassword) >= 6;

        default :
            trigger_error("Unknown password test '$test'.");
    }
}

这很糟糕,原因如下:

  • 与表单紧密耦合,始终要求字段password_control存在。如果您的数据中没有,则需要使用字段白名单或禁用验证,即:$this->User->save($this->data, true, array('field1', 'field2'))
  • 以AuthComponent的方式手动散列密码(因为没有对模型中组件的干净访问)。如果更改AuthComponent中使用的算法,则还需要在此处进行更改。

话虽如此,它可以透明地验证并为密码和密码控制字段生成正确的错误消息,而无需控制器中的任何其他代码。

答案 1 :(得分:5)

这是错误

'passwordequal' => array('checkpasswords','message' => 'Passwords dont match') 

我把它改成了

'passwordequal'  => array('rule' =>'checkpasswords','message' => 'Passwords dont match')

strcmp函数也有错误,因为它会在上面的代码中一直返回0(即False)

if(strcmp($this->data['Airline']['password'],$this->data['Airline']['confirm_password']) ==0 )
{
    return true;
}
return false;

答案 2 :(得分:3)

验证密码,旧密码和确认密码

class Adminpassword extends AppModel
{


    public $name          =  'Admin';
            public $primaryKey    =  'id';
            public $validate = array(
                'oldpassword' => array(
                        array(
                        'rule' => 'notEmpty',
                        'required' => true,
                        'message' => 'Please Enter Current password'
                        ),
                        array(
                        'rule' =>'checkcurrentpasswords',
                        'message' => 'Current Password does not match'
                        )
                ),
                'password' => array(
                        array(
                                'rule' => 'notEmpty',
                                'required' => true,
                                'message' => 'Please Enter password'
                        ),
                        array(                              
                         'rule' => array('minLength', 6),
                         'message' => 'Passwords must be at least 6 characters long.',
                        )
                ),
                'cpassword' => array(
                        array(
                        'rule' => 'notEmpty',
                        'required' => true,
                        'message' => 'Please Enter Confirm password'
                        ),
                        array(
                                'rule' => 'checkpasswords',
                                'required' => true,
                                'message' => 'Password & Confirm Password must be match.'
                        )
                )
            );

   function checkpasswords()     // to check pasword and confirm password
    {  
        if(strcmp($this->data['Adminpassword']['password'],$this->data['Adminpassword']['cpassword']) == 0 ) 
        {
            return true;
        }
        return false;
    }
    function checkcurrentpasswords()   // to check current password 
    {
        $this->id = $this->data['Adminpassword']['id'];
        $user_data = $this->field('password');       
        //print_r(Security::hash($this->data['Adminpassword']['oldpassword'], 'sha1', true));
        if ($user_data == (Security::hash($this->data['Adminpassword']['oldpassword'], 'sha1', true)))
        { 
             return true;
        }
        else
        {
         return false;
        }
    } 

}

答案 3 :(得分:2)

对于使用身份验证的CakePHP 2.x用户,您可能会注意到“AuthComponent不再自动散列它可以找到的每个密码。”即上述解决方案可能不是解决2.x问题的正确方法。 http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#hashing-passwords

答案 4 :(得分:1)

Heres是我的解决方案:

你必须创建一个名为match的方法(你可以根据自己的喜好命名):

public function match($check, $with) {
    // Getting the keys of the parent field
    foreach ($check as $k => $v) {
        $$k = $v;
    }

    // Removing blank fields
    $check = trim($$k);
    $with = trim($this->data[$this->name][$with]);

    // If both arent empty we compare and return true or false
    if (!empty($check) && !empty($with)) {
        return $check == $with;
    }

    // Return false, some fields is empty
    return false;
}

$ validate方法必须如下:

public $validate = array(
    'password' => array(
        'match' => array(
            'rule' => array('match', 'password2'),
            'message' => 'Passwords doesnt match',
        ),
    ),
);

其中password2是用于比较您的第一个password字段

的字段

我很高兴分享它! :d

答案 5 :(得分:0)