6

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

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

如何找回与正确用户关联的新密码并重置密码?

下面的代码:

控制器

    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";  
            }
}

模型_用户

    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;
}
4

2 回答 2

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进入会话并从那里检索。这是解决问题的一种方法。

于 2013-01-06T08:41:31.557 回答
0

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

  1. 如果您将重置信息与用户模型分开存储在自己的数据库表中,则可以将其他信息(如到期日期、用户 ID 和已使用标志)与令牌一起存储。用户模型将保持干净,多次重置不会相互干扰。
  2. 重置令牌不应直接存储在数据库中,而应仅存储令牌的哈希值。具有数据库读取权限(SQL 注入)的攻击者可以重置他希望的任何帐户。
  3. 令牌应该是不可预测的,md5(uniqid())如果您知道重置完成的时间,可能会严重缩小范围。

我发布了一些示例代码,介绍了这样一个密码重置过程的外观,以及一个可以生成安全令牌的类。

于 2015-03-04T09:21:48.293 回答