Сброс пароля на 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 - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.
Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.