为什么在此 Codeigniter 3 应用程序中尝试更新用户密码会失败?

Why do attempts to update a user's password in this Codeigniter 3 application fail?

我正在 Codeigniter 3.1.8 和 Bootstrap 4.

我已经为这个应用程序添加了一个注册和登录系统。我目前正在开发密码重置系统。

我不明白为什么更新用户密码失败,如下所示:

Newpassword 控制器中我有:

class Newpassword extends CI_Controller {
    private $token = NULL;

    public function index($token = NULL) {
        //echo $token; die();
        $data = $this->Static_model->get_static_data();
        $data['pages'] = $this->Pages_model->get_pages();
        $data['tagline'] = 'New password';
        $data['categories'] = $this->Categories_model->get_categories();
        $this->token = $token;
    
         // Form validation rules
         $this->form_validation->set_rules('password', 'Password', 'required|min_length[6]');
         $this->form_validation->set_rules('cpassword', 'Confirm password', 'required|matches[password]');
         $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
    
        if(!$this->form_validation->run()) {
            $this->load->view('partials/header', $data);
            $this->load->view('auth/newpassword');
            $this->load->view('partials/footer');
        } else {
            $this->add();
        }
    }

    public function add() {
        $data = $this->Static_model->get_static_data();
        $data['pages'] = $this->Pages_model->get_pages();
        $data['tagline'] = 'New password';
        $data['categories'] = $this->Categories_model->get_categories();
    
        // Encrypt new password
        $enc_password = password_hash($this->input->post('password'), PASSWORD_DEFAULT);
    
        // Update password column
        $token = $this->token;
    
        if ($this->Usermodel->set_new_password($token, $enc_password)) {
            redirect('login'); 
            $this->session->set_flashdata("new_password_success", "Your new password was set. You can login");
        } else {
            $this->session->set_flashdata("new_password_fail", "We have failed updating your password");
            redirect('/newpassword'); 
        }
      }
    }

Usermodel 模型中我有:

public function set_new_password($token, $enc_password) {
    $this->db
        ->where(['token' => $token])
        // set new password and reset token to NULL
        ->update('authors', array('password' => $enc_password, 'token' => NULL));
}

形式:

<?php echo form_open(base_url('newpassword/add')); ?>
  <div class="form-group <?php if(form_error('password')) echo 'has-error';?>">
    <input type="password" name="password" id="password" class="form-control" placeholder="Password">
    <?php if(form_error('password')) echo form_error('password'); ?> 
  </div>
  <div class="form-group <?php if(form_error('cpassword')) echo 'has-error';?>">
    <input type="password" name="cpassword" id="cpassword" class="form-control" placeholder="Confirm password">
    <?php if(form_error('cpassword')) echo form_error('cpassword'); ?> 
  </div>
  <div class="form-group mb-2">
    <input type="submit" value="Set password" class="btn btn-block btn-md btn-success">
  </div>            
<?php echo form_close(); ?>

如果我从控制器中取消注释 //echo $token; die();,令牌将打印出预期值。然而,密码没有更新(并且正确显示了更新失败)。

我做错了什么?

当您单击 设置密码 按钮时重定向到 newpassword/add 令牌 不存在,因为它仅用于上一步:

  1. 密码重置请求
  2. 点击电子邮件中的 link(令牌存在)
  3. 填写表格并点击“设置密码”(将表格数据发送至newpassword/add)-此处不存在令牌,但您想使用它:$token = $this->token; 但现在“令牌”是:add

抱歉,您必须重构密码重置代码逻辑。我认为这比重写整个过程更难修复

更新:

Newpassword controller

中的 index 方法中添加 $data['token'] = $token;

views/auth/newpassword.php 中的表单操作 url 修改为: <?php echo form_open(base_url('newpassword/add/'.$token)); ?>

重要!!!

return添加到模型中的ell函数中: return $this->db-> .... 并在 redirect('<url>') 之后 set session flashdata!

我测试了它,我认为它解决了问题。

这是密码更新的最终工作代码(以防其他人需要):

新密码控制器中:

class Newpassword extends CI_Controller
{
    public function index($token = NULL)
    {
        $data               = $this->Static_model->get_static_data();
        $data['pages']      = $this->Pages_model->get_pages();
        $data['tagline']    = 'New password';
        $data['categories'] = $this->Categories_model->get_categories();
        $data['token']      = $token;
        
        // Form validation rules
        $this->form_validation->set_rules('password', 'Password', 'required|min_length[6]');
        $this->form_validation->set_rules('cpassword', 'Confirm password', 'required|matches[password]');
        $this->form_validation->set_error_delimiters('<p class="error-message">', '</p>');
        
        if (!$this->form_validation->run()) {
            $this->load->view('partials/header', $data);
            $this->load->view('auth/newpassword');
            $this->load->view('partials/footer');
        } else {
            // Encrypt new password
            $enc_password = password_hash($this->input->post('password'), PASSWORD_DEFAULT);
            
            if ($this->Usermodel->set_new_password($token, $enc_password)) {
                $this->session->set_flashdata("new_password_success", "Your new password was set. You can login");
                redirect('login');
            } else {
                $this->session->set_flashdata("new_password_fail", "We have failed updating your password");
                redirect('/newpassword/' . $token);
            }
        }
    }
}

模型中:

public function set_new_password($token, $enc_password) {
    return $this->db
        ->where('token', $token)
        // set new password and reset token to NULL
        ->update('authors', array('password' => $enc_password, 'token' => NULL));
}

表单(视图):

<?php echo form_open(base_url('newpassword/'. $token)); ?>
  <div class="form-group <?php if(form_error('password')) echo 'has-error';?>">
    <input type="password" name="password" id="password" class="form-control" placeholder="Password">
    <?php if(form_error('password')) echo form_error('password'); ?> 
  </div>
  <div class="form-group <?php if(form_error('cpassword')) echo 'has-error';?>">
    <input type="password" name="cpassword" id="cpassword" class="form-control" placeholder="Confirm password">
    <?php if(form_error('cpassword')) echo form_error('cpassword'); ?> 
  </div>
  <div class="form-group mb-2">
    <input type="submit" value="Set password" class="btn btn-block btn-md btn-success">
  </div>            
<?php echo form_close(); ?>