Codeigniter - 忘记密码

Posted

技术标签:

【中文标题】Codeigniter - 忘记密码【英文标题】:Codeigniter - Forgot Password 【发布时间】:2012-12-20 06:26:04 【问题描述】:

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

    恢复视图提示接收到的电子邮件输入 函数email_exists() 将验证电子邮件。如果是这样,send_email()$temp_pass 键和链接。数据库将存储 $temp_pass 以供进一步操作和验证。 用户点击之前发送的链接,将 $temp_pass 传递给函数 reset_password。 模型控制器将验证$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";  
            

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;

【问题讨论】:

看看 ion auth 是怎么做的。 【参考方案1】:

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

在这一步之后,你要求用户输入他的新密码,因为你有一个临时标志,你称之为用户$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 传递到会话中并从那里检索。这是解决问题的一种方法。

【讨论】:

你是对的 $message 的语法有一个错误/错误。有趣的是,我仍然能够检索它($temp_pass)并将其传递给我的模型用户(is_temp_valid_key)进行验证。无论如何,我正在做出改变。 我不知道把你刚刚给我的那段代码放在哪里。函数 reset_password($temp_pass) 是在用户单击链接时立即启动的函数,因此它会评估 $temp_pass 是否有效并返回 true 以便加载视图以检索新密码。现在表单指向 update_password() 但不能再通过 $temp_pass 来更新数据库: $this->db->update('users', $data);因为它不知道是哪个用户??我卡在那里...非常感谢您的帮助。 实际上 php 在双引号字符串中进行变量替换,所以第一个版本实际上应该可以工作,认为使用大括号的变体被认为是一种好习惯:"main/reset_password/$temp_pass'&gt;Clic... @user1728037 您可以将$temp_pass 传递到会话中并从那里检索。这是解决问题的一种方法。 @Aniket 我迷路了,我需要在哪里开始会话?我认为它应该在视图加载之前进行,对吗?但是我的模型用户中的函数 update_password 不会更新密码。有什么帮助吗?我会很感激的......【参考方案2】:

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

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

我发布了一些example code,介绍了这样一个密码重置过程的样子,以及一个可以生成安全令牌的类。

【讨论】:

我读了你的文章。这个问题不是关于你的答案,而是关于你的网站。为什么大多数程序员(包括你)的个人网站都很难看。我的意思是您可以轻松购买 WordPress 主题并撰写博客。甚至定制设计也不需要太多时间...大多数程序员网站丑陋的原因是什么......... @IamtheMostStupidPerson - 现在好点了吗?我刚刚发布了一个新工具SilentNotes 并重新设计了网站,使其能够响应小型手机。

以上是关于Codeigniter - 忘记密码的主要内容,如果未能解决你的问题,请参考以下文章

忘记密码功能在 CodeIgniter 中不起作用

在codeigniter中忘记密码

MongoDB忘记密码怎么恢复

ipad忘记icloud密码如何注销(ipad忘记密码怎么注销icloud账户)

VMware CentOS7 忘记密码解决方法

密码忘记了怎么找回?