我在php / silex / twig中构建了一个密码重置系统,它可以向用户发送一个带有唯一令牌的密码重置链接。用户访问confirm-new-password
页面后,系统会提示您输入新密码并确认该密码。然后,我有一个函数confirm_new_password
,用于检查密码是否相同,如果它们更新该特定用户的数据库,然后删除该令牌。这一切都正常,因为我可以在数据库中看到密码更改。
但是我的问题是,当用户尝试使用他们的新密码登录时,我的flash消息会出现错误,说明如果不是这样,则详细信息是错误的。
当我使用password_hash
函数时,我认为它可能与此有关但是我在输入数据库之前对新密码进行哈希处理,并且它使用password_verify
函数运行检查在我的login
函数中。
最初我已阅读this以开始帮助构建重置功能,包括其他帮助生成随机令牌和一次有效期限的网址。
之后我读了this,这帮助我理解我需要传递隐藏的输入,以便根据哪个用户重置密码来更新post变量。但是在密码重置后似乎无法通过登录问题。
这是我的确认新密码的功能
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;
}
}
这是树枝模板;
<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>
这是后控制器代码;
$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('/');
}
});
我应该提一下,登录对其他用户来说非常好,只是在重置密码时才会停止工作。以下是登录功能;
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;
}
}
这是登录的后控制器方法;
$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');
}
});
我收到了Flash错误,说我的登录详细信息出错了
答案 0 :(得分:2)
将我的评论转为额外/免费答案。
除了给出的其他答案;我看到的方式是您正在使用name="pass1"
和name="pass2"
但您正在执行get('password1')
和get('password2')
。
将error reporting添加到文件的顶部,这有助于查找错误。
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Then the rest of your code
旁注:只应在暂存时进行显示错误,而不是生产。
答案 1 :(得分:1)
$password1 = mysqli_real_escape_string($this->link,$password1);
$password1 = password_hash($password1,PASSWORD_BCRYPT);
我会改变这些行的顺序。
首先哈希吧 - 而不是逃避它。
因为您现在的做法是,通过添加例如密码(mypass'w0rd)来逃避密码一些反斜杠(mypass \'w0rd)到原始密码,然后是哈希。