I have built a password reset system in php/silex/twig that gets sends the user a password reset link with a unique token. After the user visits the confirm-new-password
page the are prompted to enter a new password and confirm that password. I then have a function confirm_new_password
that checks whether the passwords are the same, if they are update the database of that specific user and then delete the token. This all works fine as I can see in the database that the password changes.
However my problem is that when the user try's to login with their new password I get an error with my flash messages saying that the details are wrong when this is not the case.
As I am using the password_hash
function I thought that it maybe to do with this however I am hashing the new password before its entered into the database and it is running the check using the password_verify
function within my login
function.
Initially I had read this to start of helping build the reset functionality including others to help with generating the random token and one time url with an expiry time.
Afterwards I read this which helped me to understand that I need to pass hidden inputs so that the post variables can be updated according which user is resetting their password. But could not seem to get passed the issue of the login after the password is reset.
Here is my function for the confirm-new-password
public function confirm_new_password($password1,$password2,$email,$token){
if($password1 === $password2){
$password1 = mysqli_real_escape_string($this->link,$password1);
$password1 = password_hash($password1,PASSWORD_BCRYPT);
$result = mysqli_query($this->link,"update user set password='{$password1}' where email='{$email}' ");
$result1 = mysqli_query($this->link,"update user set token='' where email = '{$email}' ");
return true;
}else{
return false;
}
}
and here is the twig template;
<form class="form-signin" action="/confirm-new-password" method="post">
<h2 class="form-heading">Confirm New Password</h2>
<label for="inputNewPass1" class="sr-only">New Password</label>
<input type="password" id="inputNewPass1" class="form-control" name="pass1" placeholder="New Password" required>
<label for="inputNewPass2" class="sr-only">Re-Type New Password</label>
<input type="password" id="inputNewPass2" class="form-control" name="pass2" placeholder="Re-type New Password" required>
{% if test is defined %}
<input type="hidden" name="email" value="{{ test.email }}">
<input type="hidden" name="token" value="{{ test.token }}">
{% endif %}
<div class="spamCheck">
<label for="inputPostcode" class=sr-only">Postcode</label>
<input type="text" id="inputPostcode" class="form-control" name="postcode" placeholder="Leave this field blank" />
</div>
<button class="btn btn-lg btn-default btn-block" type="submit">Reset Password</button>
</form>
and here is the post controller code;
$app->post('/confirm-new-password', function(Request $request) use($app){
$password1 = $app['request']->get('password1');
$password2 = $app['request']->get('password2');
$email = $app['request']->get('email');
$token = $app['request']->get('token');
if($app['auth']->confirm_new_password($password1,$password2,$email,$token)){
return $app->redirect('/login');
}else{
return $app->redirect('/');
}
});
I should mention that the login is working perfectly fine for other users, it just stops working when the password is reset. Below is the function for the login;
public function login($email, $password) {
$email = mysqli_real_escape_string($this->link, $email);
$result = mysqli_query($this->link, "select email, password,type from user where email = '{$email}'");
$row = mysqli_fetch_assoc($result);
if(password_verify($password,$row['password'])){
$user = array('email' => $row['email'], 'type' => $row['type']);
$this->session->set('user', $user);
return true;
} else {
return false;
}
}
and here is the post controller method for the login;
$app->post('/login', function(Request $request) use($app) {
$email = $app['request']->get('email');
$password = $app['request']->get('password');
$postcode = $app['request']->get('postcode');
$post = array($email,$password,$postcode);
$app['auth']->spamBotCheck($post);
$app['auth']->honeyPotCheck($postcode);
if ($app['auth']->login($email, $password)) {
$app['session']->getFlashBag()->add('success','Success! You are now logged in.');
return $app->redirect('/');
} else {
$app['session']->getFlashBag()->add('error','Error! There was an error with your login details, please try again');
return $app->redirect('/login');
}
});
I get the flash error, saying there was an error with my login details