Напоминание пароля.
Алгоритм.
Пользователь
может менять свой пароль, если он
залогинен.
Либо он может
менять свой пароль, если он его забыл.
В этом случае, он вводит свой e-mail
и ему на почту приходит ссылка со
сгененрированным токеном. Этот токен
подставляется с get-параметр.
Если токен неверный, то нам выдает
сообщение Token invalid. Если верный, то
открывается страница смены пароля.
После смены пароля сгенерированный
токен удаляется из БД.
Создадим таблицу в
БД password_tokens.
id int(11)
unsigned primary AI
token char(64)
unique
user_id int(11)
unsigned
Создадим страницу
forgot-password.php
<?php
include('./classes/DB.php');
if(isset($_POST['resetpassword'])) {
//
Генерируем токен.
$cstrong =
true;
$token =
bin2hex(openssl_random_pseudo_bytes(64, $cstrong)); // мы
генерируем 64 байта, вторым параметром
передается только перемена
$email =
$_POST['email'];
$user_id =
DB::query('SELECT id FROM users WHERE email=:email',
array(':email'=>$email))[0]['id'];
//DB::query('INSERT INTO password_tokens VALUES (\'\', :token,
:user_id)', array(':token'=>sha1($token), ':user_id'=>$user_id));
// Вставка
в таблицу password_tokens сгенерированного
токена и id пользователя
DB::query('INSERT INTO password_tokens VALUE (:id, :token,
:user_id)', array(':id'=>null, ':token'=>sha1($token),
':user_id'=>$user_id));
echo
'Email sent!';
echo '<br
/>';
echo
$token;
}
?>
<h1>Forgot
Password</h1>
<form
action="forgot-password.php" method="post">
<input
type="text" name="email" value=""
placeholder="Email..."/>
<input
type="submit" name="resetpassword" value="Reset
Password"/>
</form>
Зайдем на
страницу change-password.php и проверим передан
ли этот вновь сгенерированный токен в
get-параметрах.
Например
так:
http://newsocial.loc/change-password.php?token=c215839f1080d74f2f387a52d20325634e6839ce
На
странице http://newsocial.loc/forgot-password.php
генерируется новый токен, который мы
отображаем на странице, Например,
9afcba54b8e9a67fc02d2c4293924b478798781c6677ea0481a4fe9813cc6ec96cdbde12c8e54c0fa7ac7d1efdcf07d3ab23e4882c4053b5f150b468be99abf4
9afcba54b8e9a67fc02d2c4293924b478798781c6677ea0481a4fe9813cc6ec96cdbde12c8e54c0fa7ac7d1efdcf07d3ab23e4882c4053b5f150b468be99abf4
И
теперь на странице смены пароля мы
передаем этот токен в get-параметрах
http://newsocial.loc/change-password.php?token=9afcba54b8e9a67fc02d2c4293924b478798781c6677ea0481a4fe9813cc6ec96cdbde12c8e54c0fa7ac7d1efdcf07d3ab23e4882c4053b5f150b468be99abf4
Если
этот токен неверный, то выводится Invalid
token.
Изменим страницу
change-password.php
<?php
include('./classes/DB.php');
include('./classes/Login.php');
if(Login::isLoggedIn()) {
if(isset($_POST['changepassword'])) {
$oldpassword = $_POST['oldpassword'];
$newpassword = $_POST['newpassword'];
$newpasswordrepeat = $_POST['newpasswordrepeat'];
$userid = Login::isLoggedIn();
//
верифицируем пароль
if
(password_verify($oldpassword, DB::query('SELECT password FROM users
WHERE id=:userid', array(':userid'=>$userid))[0]['password'])) {
//
проверяем совпадение пароля и его
повтора
if($newpassword == $newpasswordrepeat) {
if(strlen($newpassword) >= 6 && strlen($newpassword) <=
60) {
DB::query('UPDATE users SET password=:newpassword WHERE
id=:userid', array(':newpassword'=>password_hash($newpassword,
PASSWORD_BCRYPT), ':userid'=>$userid));
echo 'Password changed successfully!';
}
}
else {
echo 'Password don\'t match';
}
} else
{
echo 'Incorrect old password!';
}
}
} else {
$tokenIsValid = False; // токен неверный
if(isset($_GET['token'])) {
$token
= $_GET['token'];
if(DB::query('SELECT user_id FROM password_tokens WHERE
token=:token', array(':token'=>sha1($token)))[0]['user_id']) {
$userid = DB::query('SELECT user_id FROM password_tokens WHERE
token=:token', array(':token'=>sha1($token)))[0]['user_id'];
$tokenIsValid = True; // токен верный
if(isset($_POST['changepassword'])) {
$newpassword = $_POST['newpassword'];
$newpasswordrepeat = $_POST['newpasswordrepeat'];
// проверяем совпадение пароля и его
повтора
if($newpassword == $newpasswordrepeat) {
if(strlen($newpassword) >= 6 &&
strlen($newpassword) <= 60) {
DB::query('UPDATE users SET password=:newpassword WHERE
id=:userid', array(':newpassword'=>password_hash($newpassword,
PASSWORD_BCRYPT), ':userid'=>$userid));
echo 'Password changed successfully!';
// После смены пароля, удалим
созданный токен
DB::query('DELETE FROM password_tokens WHERE
user_id=:userid', array(':userid'=>$userid));
}
} else {
echo 'Password don\'t match';
}
}
} else
{
die('Token invalid');
}
} else {
die('Not logged in');
}
}
?>
<h1>Change
your Password</h1>
<form
action="<?php if(!$tokenIsValid) {echo 'change-password.php';
} else { echo 'change-password.php?token='.$token.''; } ?>"
method="post">
<?php if
(!$tokenIsValid) { echo '<input type="password"
name="oldpassword" value="" placeholder="Current
Password ..."><p />'; } ?>
<input
type="password" name="newpassword" value=""
placeholder="New Password..."/><br />
<input
type="password" name="newpasswordrepeat" value=""
placeholder="Repeat Password..."/><br />
<input
type="submit" name="changepassword" value="Change
Password"/>
</form>
Комментариев нет:
Отправить комментарий