简体   繁体   English

蛋糕 PHP 密码重置

[英]Cake PHP Password Reset

currently working on a password reset script for a CakePHP application that I have been put in charge of.目前正在为我负责的 CakePHP 应用程序编写密码重置脚本。

So far, I have a forgot script that I created a random string, adding this to the relevant user and emailing the user with a link to reset.到目前为止,我有一个忘记脚本,我创建了一个随机字符串,将其添加到相关用户并通过电子邮件向用户发送重置链接。 (the domain name is in fact the live one) (域名实际上是活的)

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

Upon clicking the reset and loading the reset form, it seems to be skipping right to my last else statement with no token value?单击重置并加载重置表单后,它似乎直接跳到我最后一个没有令牌值的 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重置.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>

any help on this situation would be much appreciated as I am stuck, thanks!对这种情况的任何帮助将不胜感激,因为我被卡住了,谢谢!

Well,... you are not sending the token back when you submit...好吧,...当您提交时,您不会将令牌发回...

You do你做

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

and that submits the form to users/reset , not users/reset/token .并将表单提交给users/reset ,而不是users/reset/token So, either pass the token along with the action submit like this因此,要么像这样将令牌与提交的动作一起传递

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

or submit it along with the form as hidden input或将其与表单一起作为隐藏输入提交

  <?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)
  ?>

and get it in the controller like并将其放入控制器中

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

In the future, don't expect forms to submit all the values you passed by url, it's not how things work :(将来,不要指望表单提交您通过 url 传递的所有值,这不是事情的工作方式:(

Security tip安全提示

If I were evil, or if Voldemort knew internet, he could try to do call your reset url with random tokens to change passwords to voldi-rocks and then try and access the site.如果我是邪恶的,或者如果伏地魔知道互联网,他可以尝试使用随机令牌调用您的重置 URL 以将密码更改为voldi-rocks ,然后尝试访问该站点。 I recommend having a valid time for the reset token, if the reset link isn't used within one hour (for example), invalidate it.我建议为重置令牌设置一个有效时间,如果一小时内未使用重置链接(例如),请将其失效。

Tip of the day每日提示

You can put public $recursive = -1;你可以把public $recursive = -1; on your User model to avoid putting it on every action in the controller.在您的用户模型上,以避免将其放在控制器中的每个操作上。

我们发现您必须在 reset.ctp 中登顶注册表中显示的其余必填字段,当然是隐藏的,并且一切正常,包括更新密码字段。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM