我很想知道:一旦通过电子邮件发送了 pw_reset 令牌,是否可以获取推荐人帐户的电子邮件地址进行验证,或者最好针对 IP 进行验证?我已将我的令牌设置为仅 1 小时过期,即使是动态 IP 也不会以该速率更改,对吗?
我正在玩的一些代码(非常 WIP),对改进/建议/批评开放。
提前致谢。
/**
* Reset Password Form
*
* $route['auth/reset-password'] = 'reset_password_form';
*
*/
public function reset_password_form()
{
$this->load->view('templates/public', array(
'content' => 'auth/reset_password_form',
'title' => 'Password reset',
'description' => '',
'canonical' => 'auth'
));
}
/**
* Reset Password Authentication
*
* $route['auth/reset_password/validate'] = 'auth/reset_password';
*
*/
public function reset_password()
{
//setup validation rules
$config = array(
array('field'=>'email_address', 'label' =>'Email address', 'rules'=>'trim|required|max_lenght[128]|valid_email|valid_user_email')
);
$this->form_validation->CI =& $this;
$this->form_validation->set_rules($config);
//run validator and confirm OR
if($this->form_validation->run($this))
{
//create the token data
$tokenhash = Auth::create_token();
$password_token = json_encode(array(
'token' => $tokenhash,
'expires' => date('h:i:s A', strtotime($this->config->item('pw_token_expires'))), // default 1 hours
'ip_address' => $this->input->ip_address()
)); // output {"token":"3513f5ee34ED3","expires":"01:14:06 AM","ip_address":"127.0.0.1"}
//grab a userid to use via php-activerecord custom USER model
$user = User::get_by_email_address($this->input->post('email_address'));
//update the user pw_token field
try{
if($user->update_attribute('pw_token', $password_token))
{
throw new \ActiveRecord\ActiveRecordException($user->errors);
}
}catch(\ActiveRecord\ActiveRecordException $e){
log_message('error', $e->getMessage());
}
//setup email data
//TODO : move this to USER activeRecord\Model (pre_)
$email_data = array(
'email_to' => $user->email_address,
'token' => anchor(site_url('auth/reset_password/confirm/'.$tokenhash.'/'.$user->id.''), 'click here to reset your password'),
'site_link' => anchor(site_url(), site_url())
);
try{
if(Mail::send($email_data, 'reset_password.tpl.html'))
{
throw new Exception(Mail::errors());
}
}catch(Exception $e){
log_message('error', $e->getMessage());
}
}
else
{
$this->reset_password_form();
}
}
/**
* Reset Password Confirmation
*
* $route['auth/reset_password/confirm/(:any)/(:num)'] = 'auth/confirm_password_reset';
*/
public function confirm_password_reset($token='', $userid='')
{
//check for null values
if(!$token || !$id)
{
redirect('/');
}
//ugly
$attempts = $this->session->set_userdata('reset_pw_attempt', (int)0);
$this->session->set_userdata('reset_pw_attempts', $attempts++);
if(!$this->user->id != $userid && $this->session->userdata('logged_in') === (int)0)
{
//not great but cant validate the email, so we check to see if they have a logged in session.
//this is not a "forgot_password request" so we should be good as long as they are logged in
show_404();
}
else
{
//looking good so far, now lets see do they have the correct permissions
if(in_array(PERM_UPDATE, Auth::permissions($this->user->permissions)))
{
if($attempts == (int)3)
{
$this->session->set_flashdata('', $this->lang->line('pw_reset_attempt_over'));
redirect('/');
}
else
{
$tokn[] = json_decode($this->user->pw_token);
if(date('h:i:s A', time()) > $tokn['expires'] && $token===$tokn['token'])
{
$this->load->view('do-pw_reset_form');
}
}
}
else
{
$this->session->set_flashdata('info', $this->lang->line('update_permission_denied'));
redirect('/');
}
}
}