Cake PHP密码重置

时间:2014-05-13 15:19:02

标签: php cakephp

目前正在处理我负责的CakePHP应用程序的密码重置脚本。

到目前为止,我有一个忘记的脚本,我创建了一个随机字符串,将其添加到相关用户并通过电子邮件向用户发送重置链接。 (域名实际上是直播域名)

Click on the link below to Reset Your Password


Click here to Reset Your Password
or Visit this Link

domainnamehere/users/reset/e9bb0ab37ff9175a856f0aff3e18db801451306e5a50bfc618c43280b62628e4bdb8131b638e042b47d42ca1516de11f1b025d646406bfd31054db167d5ef430#62442a331b1f9a3e37cbb9a33c1d619b8a8e0a18

This email was sent using the CakePHP Framework

点击重置并加载重置表单后,它似乎正在跳过我最后一个没有令牌值的else语句?

function reset($token=null){
    //$this->layout="Login";
    $this->User->recursive=-1;
    if(!empty($token)){
        $u=$this->User->findBytokenhash($token);
        if($u){
            $this->User->id=$u['User']['id'];
            if(!empty($this->data)){
                $this->User->data=$this->data;
                $this->User->data['User']['username']=$u['User']['username'];
                $new_hash=sha1($u['User']['username'].rand(0,100));//created token
                $this->User->data['User']['tokenhash']=$new_hash;
                if($this->User->validates(array('fieldList'=>array('password','password_retype')))){
                    if($this->User->save($this->User->data))
                    {
                        $this->Session->setFlash('Password Has been Updated');
                        $this->redirect(array('controller'=>'users','action'=>'login'));
                    }
                    else
                    {
                        $this->Session->setFlash('Error updating values');
                    }

                }
                else{

                    $this->set('errors',$this->User->invalidFields());
                }
            }
        }
        else
        {
            $this->Session->setFlash('Token Corrupted,,Please Retry.the reset link work only for once.');
        }
    }
    else{
        // $this->redirect('/');
      $this->Session->setFlash($token);
    }
}

reset.ctp

<div class="users form">
   <?php echo $this->Form->create('User', array('action' => 'reset')); ?>
   <fieldset>
      <legend><?php echo __('Change your Password'); ?></legend>
      <?php
      //debug($users);
      echo $this->Form->input('password', array('label' => 'Change password'));
      echo $this->Form->input('password_retype', array('label' => 'Confirm password', 'type' => 'password'));
      ?>
   </fieldset>
   <?php echo $this->Form->end(__('Submit')); ?>
</div>

对于这种情况的任何帮助都会非常感激,因为我被卡住了,谢谢!

3 个答案:

答案 0 :(得分:2)

嗯,......当你提交时,你没有发回令牌......

你做

<?php echo $this->Form->create('User', array('action' => 'reset')); ?>

并将表单提交到users/reset,而不是users/reset/token。因此,要么将令牌与动作提交一起传递,就像这样

<?php echo $this->Form->create('User', array('action' => 'reset', $token)); ?>

或将其与表单一起提交为隐藏输入

  <?php
  //debug($users);
  echo $this->Form->input('password', array('label' => 'Change password'));
  echo $this->Form->input('password_retype', array('label' => 'Confirm password', 'type' => 'password'));

  //here
  echo $this->Form->input('token', array('type'=>'hidden', 'value'=>$token)
  ?>

并在控制器中获取

if (!empty($token) && !empty($this->request->data['User']['token'])) {

将来,不要期望表单提交您通过url传递的所有值,这不是事情的运作方式:(

安全提示

如果我是邪恶的,或者如果Voldemort知道互联网,他可以尝试使用随机令牌调用您的重置URL来将密码更改为voldi-rocks,然后尝试访问该网站。我建议有一个有效的重置令牌时间,如果一小时内未使用重置链接(例如),则使其无效。

当天提示

您可以将public $recursive = -1;放在用户模型上,以避免将其放在控制器中的每个操作上。

答案 1 :(得分:0)

我们发现你必须在reset.ctp中登记注册表单中显示的其他必填字段,当然是隐藏的,一切都很完美,包括更新密码字段。

答案 2 :(得分:0)

function admin_forgotpwd() {

        if (count($this->Session->read("Auth.User"))) {
            return $this->redirect('/');
        }

        $this->set('title_for_layout', 'Forgot Password');

        $this->layout = 'admin_login';
        $this->User->recursive = -1;
        if (!empty($this->data)) {
            if (empty($this->data['User']['email'])) {
                $this->Session->setFlash(__('Please enter your email.'), 'default', array('class' => 'alert alert-success'));
            } else {
                $email = $this->data['User']['email'];
                $fu = $this->User->find('first', array('conditions' => array('User.email' => $email)));
                if ($fu) {
                    //debug($fu);
                    if ($fu['User']['user_status'] == 'active') {
                        $key = Security::hash(String::uuid(), 'sha512', true);
                        $hash = sha1($fu['User']['username'] . rand(0, 100));
                        $url = Router::url(array('controller' => 'users', 'action' => 'reset'), true) . '/' . $key . '#' . $hash;
                        $ms = $url;
                        $ms = wordwrap($ms, 1000);
                        debug($url);
                        $fu['User']['tokenhash'] = $key;
                        $this->User->id = $fu['User']['id'];
                        if ($this->User->saveField('tokenhash', $fu['User']['tokenhash'])) {




                            $this->Session->setFlash(__('Check your email to reset password.', true), 'default', array('class' => 'alert alert-success'));
                            $this->redirect(array('controller' => 'users', 'action' => 'login'));
                            //============EndEmail=============//
                        } else {
                            $this->Session->setFlash(__("Error while generating reset link."), 'default', array('class' => 'alert alert-danger'));
                        }
                    } else {
                        $this->Session->setFlash(__('This account is not active yet.'), 'default', array('class' => 'alert alert-danger'));
                    }
                } else {
                    $this->Session->setFlash(__('Email does not exist'), 'default', array('class' => 'alert alert-danger'));
                }
            }
        }
    }