重置密码,数据库更新后出现登录错误


Resetting password, login error after database update

我在php/silex/tritch中构建了一个密码重置系统,该系统将向用户发送一个带有唯一令牌的密码重置链接。用户访问confirm-new-password页面后,系统会提示用户输入新密码并确认该密码。然后,我有一个函数confirm_new_password,它检查密码是否相同,如果它们更新了特定用户的数据库,然后删除了令牌。这一切都很好,正如我在密码更改的数据库中看到的那样。

然而,我的问题是,当用户尝试使用他们的新密码登录时,我的闪屏信息会出错,说详细信息是错误的,而事实并非如此。

当我使用password_hash函数时,我认为它可能会这样做,但我在将新密码输入数据库之前对其进行哈希处理,并且它正在使用我的login函数中的password_verify函数运行检查。

最初,我读到这篇文章是为了开始帮助构建重置功能,包括帮助生成随机令牌和带有到期时间的一次性url的其他功能。

之后,我读了这篇文章,这帮助我理解了我需要传递隐藏的输入,以便根据哪个用户正在重置他们的密码来更新后变量。但似乎无法通过密码重置后的登录问题。

这是我确认新密码的功能

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错误,说我的登录详细信息

有错误
$password1 = mysqli_real_escape_string($this->link,$password1);  
$password1 = password_hash($password1,PASSWORD_BCRYPT);

我会更改这些行的顺序
首先散列它,而不是逃避它。

因为你现在的做法是,通过在原始密码中添加一些反斜杠(mypass'''word)来转义密码(mypass'word

把我的评论变成一个额外的/赞美的回答。

除了给出的其他答案之外;我看到的是,您使用的是name="pass1"name="pass2",而您使用的却是get('password1')get('password2')

  • 他们需要匹配

错误报告添加到文件顶部,这将有助于查找错误。

<?php 
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Then the rest of your code

旁注:显示错误只能在暂存中进行,而不能在生产中进行。