0

Cakephp 2.0 ACL プラグインと Voidet SignMeUp プラグインを組み合わせて、完全なユーザー管理 (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' => '*****'

)

したがって、私が理解しようとしているのは、ユーザー モデルから発生するこのエラーを処理する方法です。わかる?

4

1 に答える 1

0

このエラーから

通知 (8): 未定義のインデックス: password2 [APP\Plugin\AclManagement\Model\User.php、119 行目]

そして、このエラーコンテキスト:

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

save に渡されたデータにフィールドがありませんpassword2

save を呼び出してパスワードを更新する

関連する関数は次のようです: __generateNewPassword. passwordとの両方password2が同じ値で存在することを確認するだけで、動作するはずです。

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 文字の長さになるハッシュされたパスワードにそのルールを適用します。電子メールでパスワードを送信することも、パスワード リセット ロジックを処理する最良の方法ではありません。電子メールで平文のパスワードを送信するよりも、ユーザーに新しいパスワードを自分で設定するよう依頼する方がはるかに優れています。

于 2013-01-15T22:37:53.043 に答える