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'>Clic...
@user1728037 您可以将$temp_pass
传递到会话中并从那里检索。这是解决问题的一种方法。
@Aniket 我迷路了,我需要在哪里开始会话?我认为它应该在视图加载之前进行,对吗?但是我的模型用户中的函数 update_password 不会更新密码。有什么帮助吗?我会很感激的......【参考方案2】:
我想对您的密码重置程序提出一些改进建议。
-
如果您将重置信息与用户模型分开存储在自己的数据库表中,则可以将其他信息(如到期日期、用户 ID 和已使用标志)与令牌一起存储。用户模型将保持干净,多次重置不会相互干扰。
重置令牌不应直接存储在数据库中,而应仅存储令牌的 散列。具有数据库读取权限(SQL 注入)的攻击者可以重置他希望的任何帐户。
令牌应该是不可预测的,如果您知道重置完成的时间,
md5(uniqid())
可能会缩小范围。
我发布了一些example code,介绍了这样一个密码重置过程的样子,以及一个可以生成安全令牌的类。
【讨论】:
我读了你的文章。这个问题不是关于你的答案,而是关于你的网站。为什么大多数程序员(包括你)的个人网站都很难看。我的意思是您可以轻松购买 WordPress 主题并撰写博客。甚至定制设计也不需要太多时间...大多数程序员网站丑陋的原因是什么......... @IamtheMostStupidPerson - 现在好点了吗?我刚刚发布了一个新工具SilentNotes 并重新设计了网站,使其能够响应小型手机。以上是关于Codeigniter - 忘记密码的主要内容,如果未能解决你的问题,请参考以下文章