CakePHP密码验证

7
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]

1
$this->datadata 是否是你想要的?如果不是,那就是问题所在了。 - Stephen
我修复了上面的代码以删除多余的数据,但仍然出现错误。 - aWebDeveloper
我能看一下提交数据的HTML表单吗? - Stephen
1
你的checkpassword函数中的“确认密码”是否缺少下划线? - Tim
2
如果字符串相等,strcmp 返回 0。但 0 将被理解为 false,因此它会做与您预期的完全相反的事情。 - deceze
6个回答

12

你是否正在使用 AuthComponent?请注意它会对所有传入的密码字段进行哈希处理(但不包括“确认密码”字段,请通过debug($this->data)检查),因此这些字段将永远不相同。请阅读手册并使用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 中使用的算法,则还需要在此处进行更改。

尽管如此,该方法仍然能够透明地验证并生成正确的错误消息,而无需在控制器中添加任何额外的代码。


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;

6
哦,这个冗余太可怕了!在这种情况下,你应该使用 return strcmp(...) == 0 - deceze

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;
        }
    } 

}

2

1
这是我的解决方案:
您需要创建一个名为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


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接