Сброс пароля на PHP
Одна из целей разработки учебных проектов – это возможность разобраться с тем, как внутри работают некоторые процессы. Это относится и к функции сброса пароля пользователя (если забыл), которая реализована во всех крупных кмс, крм и фреймворках по умолчанию. Но полезно реализовать и самостоятельный вариант – хотя бы в учебных целях – давайте этим и займёмся.
Ход решения
Сначала посмотрим, что уже внутри есть у нашего веб-приложения (то бишь сайта). А видим мы обычную таблицу пользователей с оригинальным названием users и четырьмя полями – ид, логин, пароль и right (понятно, что это что-то типа прав доступа). Что ж, тогда реализуем самый простой вариант (не забываем, что у нас учебный проект).
Этапы:
- Добавляем в таблицу users два поля: email и reset_token.
- На форму регистрации добавляем инпут для электронной почты.
- В скрипт (функцию регистрации) вставляем добавление поля email.
- Создаем форму для ввода email для сброса.
- Создаем функцию, проверяющую, есть ли введенный mail в системе, создающую токен и отправляющую ссылку для сброса на почту.
- Создаем форму для ввода нового пароля.
- Создаем функцию, которая вызывается при переходе по этой ссылке – которая собственно и сбрасывает пароль на введенный.
1 Миграция
Добавление полей в таблицу – это обычная миграция, sql-запрос. Тут будет что-то типа такого
ALTER TABLE `users` ADD `email` VARCHAR(255) NOT NULL AFTER `reset_token`, ADD `reset_token` VARCHAR(255) NOT NULL DEFAULT '0' AFTER `rights`;Получаем такую вот структуру:
2 Тег input для почты
Тоже все просто:
<input requred name="email" type="email" size="50" placeholder="email" />3 Вставка email
Наверно надо было сразу написать, ну да ладно, можно и сейчас. Дело в том, что мы модифицируем уже имеющийся скрипт; у вас может быть другая схема, но все же в большинстве случаев шаги могут быть именно такими. Так что не стоит бездумно копировать код, я просто пишу ход решения, а строки кода – это как бы иллюстрация реализации, не более.
Здесь у нас обычное подключение (расширение драйвера) MySQLi. Модифицируем функцию добавления пользователя таким образом:
function addNewUser($login, $password, $role, $email){
global $link;
$query = "INSERT INTO `users` (`id`,`login`,`password`,`rights`,`email`,`reset_token`) VALUES (NULL,'$login','$password','$role','$email','0');";
$result = mysqli_query($link, $query) or die (mysqli_error($link));
$id = mysqli_insert_id($link);
return $id;
}
Обращаю внимание, что перед вставкой надо либо проверить на sql-иньекцию вводимые поля, либо же использовать параметризованный запрос, что-то типа mysqli_stmt_bind_param.
4 Форма для ввода email
Громко звучит – форма, на самом деле одно поле + кнопка отправки. Что-то типа такого наваяем:
<form action="<?php echo $form_action; ?>" method="POST">
<p>Введите email, на который будет отправлена ссылка для сброса пароля</p>
<p><input requred name="email" type="email" size="30" placeholder="email"
<p>Введите новый пароль</p>
<p><input requred name="password" type="password" size="30" placeholder="пароль" /></p>
<p><input class="btn btn-success pull-right" type="submit" value="Отправить"/></p>
</form>
5 Проверка, отправка письма
После того, как пользователь введет свой email и нажмет кнопку «Отправить»
If( !checkUserEmail($email)){
echo "пользователь с таким email не найден в базе данных!"; }
else {
//создаем токен и записываем его в базу данных
$reset_token = hash('sha384', time().$email.);
updateRow("users", "reset_token", $reset_token, "email", $email);
//формируем ссылку для сброса пароля
$href = $site."/reset.php?reset_token=".$reset_token."&email=".$email;
//формируем письмо
$subject = 'Сброс пароля';
$message = "Для сброса пароля перейдите по ссылке $href";
$headers = 'From: qwerty@mail.ru' . "\r\n" .
'Reply-To: wqerty@mail.ru' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
//отправляем письмо
if (mail($email, $subject, $message, $headers)
6 Форма для нового пароля
<form action="<?php echo $form_action; ?>" method="POST">
<p>Введите новый пароль</p>
<p><input requred name="password" type="password" size="30" placeholder="пароль" /></p>
<p><input class="btn btn-success pull-right" type="submit" value="Отправить"/></p>
</form>
7 Меняем пароль на новый
if (isset($_GET["reset_token"]) && isset($_GET["email"])){
$reset_token = $_GET["reset_token"];
$email = $_GET["email"];
$form_action = $form_action."?reset_token=$reset_token&email=$email";
//проверяем токен и почту
if (!$reset_token){
$err ="ошибка";
echo "<div class='alert alert-danger alert-dismissible fade show' role='alert'>$err
<button type='button' class='close' data-dismiss='alert' aria-label='Close'>
<span aria-hidden='true'>×</span>
</button>
</div>";
}else {
$uid = getUserIdFromResetToken($reset_token, $email);
if ($uid <=0){
$err ="ошибка";
echo "<div class='alert alert-danger alert-dismissible fade show' role='alert'>$err
<button type='button' class='close' data-dismiss='alert' aria-label='Close'>
<span aria-hidden='true'>×</span>
</button>
</div>";
}
else if (isset($_POST["password"])){
$password = $_POST["password"];
$err2 = checkUserPassword($password);
//проверяем пароль
if ($err2){
echo "<div class='alert alert-danger alert-dismissible fade show' role='alert'>
Ошибки пароля: $err2
<button type='button' class='close' data-dismiss='alert' aria-label='Close'>
<span aria-hidden='true'>×</span>
</button>
</div>";
}
else{
//обнуляем токен и меняем пароль в базе
updateRow("users", "reset_token", '0', "email", $email);
updateRow("users", "password", $password, "email", $email);
}
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Программы на заказ
Отзывы
Контакты