我在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
旁注:显示错误只能在暂存中进行,而不能在生产中进行。