【问题标题】:how to resolve cakephp password reset model validation error如何解决 cakephp 密码重置模型验证错误
【发布时间】:2013-01-15 21:01:57
【问题描述】:

我将 cakephp 2.0 ACL plugin 与 Voidet SignMeUp plugin 结合起来,以获得完整的用户管理(ACL、注册、忘记密码)。我已经完成了 SignMeUp 部分的 ACL 管理和注册工作。我遇到的问题是 SignMeUp 的忘记密码方法。

这里是忘记密码的视图:

<h2>Reset Your Password</h2>
<p>Please enter your email address below:</p>
<?php
echo $this->Form->create();
echo $this->Form->input('email');
echo $this->Form->end('Reset Password');

这里是 SignMeUp 忘记密码组件:

    public function forgottenPassword() {
    extract($this->settings);
    $model = $this->controller->modelClass;
    if (!empty($this->controller->request->data[$model])) {
        $data = $this->controller->request->data[$model];
    }

    //User has code to reset their password
    if (!empty($this->controller->request->params[$password_reset_field])) {
        $this->__generateNewPassword($model);
    } elseif (!empty($password_reset_field) && !empty($data['email'])) {
        $this->__requestNewPassword($data, $model);
    }
}

private function __generateNewPassword($model = '') {
    extract($this->settings);
    $user = $this->controller->{$model}->find('first', array(
        'conditions' => array($password_reset_field => $this->controller->request->params[$password_reset_field]),
        'recursive' => -1
    ));

    if (!empty($user)) {
        $password = substr(Security::hash(String::uuid(), null, true), 0, 8);
        $user[$model][$password_field] = Security::hash($password, null, true);
        $user[$model][$password_reset_field] = null;
        $this->controller->set(compact('password'));
        if ($this->controller->{$model}->save($user) && $this->__sendNewPassword($user[$model])) {
            if (!$this->controller->request->is('ajax')) {
                $this->Session->setFlash('Thank you '.$user[$model][$username_field].', your new password has been emailed to you.');
                $this->controller->redirect($this->Auth->loginAction);
            } else {
                return true;
            }
        }
    }
}

    private function __requestNewPassword($data = array(), $model = '') {
    extract($this->settings);
    $this->controller->loadModel($model);
    $user = $this->controller->{$model}->find('first', array('conditions' => array('email' => $data['email']), 'recursive' => -1));
    if (!empty($user)) {
        $user[$model][$password_reset_field] = md5(String::uuid());

        if ($this->controller->{$model}->save($user) && $this->__sendForgottenPassword($user[$model])) {
            if (!$this->controller->request->is('ajax')) {
                $this->Session->setFlash('Thank you. A password recovery email has now been sent to '.$data['email']);
                $this->controller->redirect($this->Auth->loginAction);
            } else {
                return true;
            }
        }
    } else {
        $this->controller->{$model}->invalidate('email', 'No user found with email: '.$data['email']);
    }
}

这是用户模型代码:

    App::uses('AclManagementAppModel', 'AclManagement.Model');
    class User extends AclManagementAppModel {
    public $name = 'User';
    public $useTable = "users";
    public $actsAs = array('Acl' => array('type' => 'requester'), 'SignMeUp.SignMeUp');
    public $validate = array(
            'name' => array(
            'required' => false,
            'allowEmpty' => false,
            'rule' => 'notEmpty',
            'message' => 'You must enter your real name.'
        ),
        'email' => array(
            'email' => array(
                'required' => false,
                'allowEmpty' => false,
                'rule' => 'email',
                'message' => 'Invalid email.',
                'last' => true
            ),
            'unique' => array(
                'required' => false,
                'allowEmpty' => false,
                'rule' => 'isUnique',
                'message' => 'Email already in use.'
            )
        ),
        'password' => array(
            'required' => false,
            'allowEmpty' => false,
            'rule' => 'comparePwd',
            'message' => 'Password mismatch or less than 6 characters.'
        )
    );` 



public function comparePwd($check) {
    $check['password'] = trim($check['password']);

    if (!isset($this->data['User']['id']) && strlen($check['password']) < 6) {
        return false;
    }

    if (isset($this->data['User']['id']) && empty($check['password'])) {
        return true;
    }

    $r = ($check['password'] == $this->data['User']['password2'] && strlen($check['password']) >= 6);

    if (!$r) {
        $this->invalidate('password2', __d('user', 'Password missmatch.'));
    }

    return $r;
}`

这是我在提交表单时收到的错误消息:

注意(8):未定义索引:password2 [APP\Plugin\AclManagement\Model\User.php,第 119 行]

与这条消息相关的代码是:

$r = ($check['password'] == $this->data['User']['password2'] && strlen($check['password']) >= 6);

上下文状态:

$check = array(
'password' => '*****'

)

所以,我想了解的是如何处理来自用户模型的这个错误。有意义吗?

【问题讨论】:

    标签: cakephp passwords


    【解决方案1】:

    从此错误

    注意(8):未定义索引:password2 [APP\Plugin\AclManagement\Model\User.php,第 119 行]

    还有这个错误上下文:

    $check = array(
         'password' => '*****'
    );
    

    传递给保存的数据缺少字段password2

    调用save更新密码

    看起来相关函数是:__generateNewPassword。只需确保 passwordpassword2 都存在相同的值,它应该可以工作:

    private function __generateNewPassword($model = '') {
        ...
    
        if (!empty($user)) {
            $password = substr(Security::hash(String::uuid(), null, true), 0, 8);
            $hashedPw = Security::hash($password, null, true);
            $user[$model]['password'] = $hashedPw;
            $user[$model]['password2'] = $hashedPw;
            ...
    

    如果这不是导致错误的保存调用 - 检查错误堆栈跟踪以查看在您的情况下调用保存的位置。

    请注意,验证功能是一个非常糟糕的实现。密码必须经过哈希处理才能正确存储 - “必须超过 6 个字符”的验证逻辑将该规则 应用于哈希密码,该密码始终为 40 个字符长。通过电子邮件发送密码也不是处理密码重置逻辑的最佳方式 - 要求用户自己设置新密码要好得多,而不是通过电子邮件以纯文本形式发送密码。

    【讨论】:

    • 感谢 AD7six,这是我的理解。但是,只有电子邮件有输入而不是密码。我想我从组件中了解到,如果电子邮件存在,则生成一个新密码并发送它。但是当它到达模型时,它试图比较一个不存在的密码2。这有意义吗?
    • 我怀疑它是如何工作的,否则只要知道用户的电子邮件,您就可以重置他们的密码。应该是:请求重置密码 -> 发送电子邮件 -> 用户点击电子邮件中的链接 -> [密码更改过程]
    • 再次感谢。我将处理散列密码以及发送票证而不是更改密码的选项。会回来报告的。
    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 2015-07-25
    • 1970-01-01
    • 2011-05-11
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多