Codeigniter - 忘记密码

时间:2013-01-06 08:11:05

标签: codeigniter passwords

您好:我需要在登录页面上实现忘记密码。在这里,我解释了到目前为止我所拥有的

  1. 恢复视图提示收到电子邮件输入
  2. 功能email_exists()将验证电子邮件。如果是,send_email()带有$temp_pass密钥和链接。数据库将存储$ temp_pass以进行进一步操作和验证。
  3. 用户点击之前通过$temp_pass发送到功能reset_password的链接。
  4. 模型控制器将使用数据库验证$temp_pass。如果是这样,加载视图以输入新密码 - 这就是我被卡住的地方,因为表单指向一个无法识别$temp_pass因此无法重置密码的控制器。
  5. 如何检索与正确用户关联的新密码并重置密码?

    以下代码:

    控制器

        public function recover(){
        //Loads the view for the recover password process.
        $this->load->view('recover');
    }
    public function recover_password(){
        $this->load->library('form_validation');
        $this->form_validation->set_rules('email', 'Email', 'required|trim|xss_clean|callback_validate_credentials');
    
                //check if email is in the database
            $this->load->model('model_users');
            if($this->model_users->email_exists()){
                //$them_pass is the varible to be sent to the user's email 
                $temp_pass = md5(uniqid());
                //send email with #temp_pass as a link
                $this->load->library('email', array('mailtype'=>'html'));
                $this->email->from('user@yahoo.com', "Site");
                $this->email->to($this->input->post('email'));
                $this->email->subject("Reset your Password");
    
                $message = "<p>This email has been sent as a request to reset our password</p>";
                $message .= "<p><a href='".base_url()."main/reset_password/$temp_pass'>Click here </a>if you want to reset your password,
                            if not, then ignore</p>";
                $this->email->message($message);
    
                if($this->email->send()){
                    $this->load->model('model_users');
                    if($this->model_users->temp_reset_password($temp_pass)){
                        echo "check your email for instructions, thank you";
                    }
                }
                else{
                    echo "email was not sent, please contact your administrator";
                }
    
            }else{
                echo "your email is not in our database";
            }
    }
    public function reset_password($temp_pass){
        $this->load->model('model_users');
        if($this->model_users->is_temp_pass_valid($temp_pass)){
    
            $this->load->view('reset_password');
    
        }else{
            echo "the key is not valid";    
        }
    
    }
    public function update_password(){
        $this->load->library('form_validation');
            $this->form_validation->set_rules('password', 'Password', 'required|trim');
            $this->form_validation->set_rules('cpassword', 'Confirm Password', 'required|trim|matches[password]');
                if($this->form_validation->run()){
                echo "passwords match"; 
                }else{
                echo "passwords do not match";  
                }
    }
    

    Model_users

        public function email_exists(){
        $email = $this->input->post('email');
        $query = $this->db->query("SELECT email, password FROM users WHERE email='$email'");    
        if($row = $query->row()){
            return TRUE;
        }else{
            return FALSE;
        }
     }
    public function temp_reset_password($temp_pass){
        $data =array(
                    'email' =>$this->input->post('email'),
                    'reset_pass'=>$temp_pass);
                    $email = $data['email'];
    
        if($data){
            $this->db->where('email', $email);
            $this->db->update('users', $data);  
            return TRUE;
        }else{
            return FALSE;
        }
    
    }
    public function is_temp_pass_valid($temp_pass){
        $this->db->where('reset_pass', $temp_pass);
        $query = $this->db->get('users');
        if($query->num_rows() == 1){
            return TRUE;
        }
        else return FALSE;
    }
    

2 个答案:

答案 0 :(得分:0)

我不太确定你被困在哪里。我可以得到一个事实,即您正在为用户创建一个临时标志,您可以在用户单击链接时验证该标志。因此,这意味着,您可以在此时开始会话,并且只有在特定会话处于活动状态时,用户才能重置密码。

在此步骤之后,您要求用户输入他的新密码,因为您有一个临时标志,您为该用户调用$temp_pass(请注意它应该是唯一的),那么您可以找到试图重置密码的用户。

因此,您需要做的就是运行此类数据库查询 -

$this->db->where('reset_pass', $temp_pass);
$this->db->update('users', $data); // where $data will have the fields with values you are updating

我猜你犯了错误

另外,我刚注意到你的recover_password()函数 -

$message .= "<p><a href='".base_url()."main/reset_password/$temp_pass'>Click here </a>if you want to reset your password, if not, then ignore</p>";

上述行不应该是 -

$message .= "<p><a href='".base_url()."main/reset_password/".$temp_pass."'>Click here </a>if you want to reset your password, if not, then ignore</p>";

更新

您可以将$temp_pass传递到会话中并从那里检索。这是解决问题的一种方法。

答案 1 :(得分:0)

我想建议您对密码重置程序进行一些改进。

  1. 如果将重置信息与用户模型分开存储在自己的数据库表中,则可以存储其他信息,如失效日期,用户标识和已使用标记以及标记。用户模型将保持清洁,多次重置不会相互干扰。
  2. 重置令牌不应直接存储在数据库中,而应仅存储令牌的哈希。具有对数据库的读访问权的攻击者(SQL注入)可以重置他想要的任何帐户。
  3. 令牌应该是不可预测的,如果您知道重置的时间,md5(uniqid())可能会严重缩小。
  4. 我发布了一些example code,这样的密码重置过程可能是什么样子,以及一个可以生成安全令牌的类。