Форма восстановления пароля

восстановление пароля

У нас уже созданы формы регистрации и авторизации и реализован функционал подтверждения адреса электронной почты, настало время добавить функционал восстановления пароля.

Замечание! Перед тем как продолжить, рекомендую сначала прочитать предыдущие статьи, связанные с созданием формы регистрации и авторизации. Если Вы это уже сделали, то можете идти дальше.

Исходный архив, который содержит файлы, созданные в предыдущие статьи, Вы можете скачать по этой ссылке .

Замечание! После скачивания архива с исходными файлами статьи, не забудьте поменять данные для подключения к базе данных и указать адрес Вашего сайта. Всё это нужно сделать в файле dbconnect.php.

И так приступим. Первое что нам нужно сделать, это добавить ссылку " Забыли пароль? ", на страницу авторизации рядом с кнопкой " Войти ".

Открываем файл " form_auth.php ", и сразу после ячейки с кнопкой " Войти ", добавляем ячейку со ссылкой " Забыли пароль? ", которая будет ввести на файл " reset_password.php ".

        <tr>
            <td>
                <input type="submit" name="btn_submit_auth" value="Войти" />
            </td>
            <td>
                <a href="reset_password.php">Забыли пароль?</a>
            </td>
        </tr>
    
забыли пароль

Файл " reset_password.php " будет отвечать за вывод страницы восстановления пароля.

Алгоритм восстановления пароля

Каким образом будет происходить восстановление пароля ?

На страницу восстановления пароля, попросим пользователя ввести свой почтовый адрес. При обработке данной формы мы проверим, зарегистрирован ли пользователь с таким почтовым адресом, если да, то на указанный почтовый адрес отправим письмо со ссылкой, которая будет ввести на страницу установки нового пароля, иначе, если такой пользователь не зарегистрирован то, выведем сообщение об ошибке.

И так, создаём файл " reset_password.php " и пишем код.

        <?php
            //Подключение шапки
            require_once("header.php");
        ?>
    

Добавляем блок JavaScript кода, для проверки формата введённого почтового адреса. То есть с помощью этого кода мы проверяем, ввёл ли пользователь правильный почтовый адрес.

        
    

Дальше, добавим блок для вывода разных сообщений. Эти сообщения мы будем добавлять в сессию при обработке формы с этой страницы.

        
        <div class="block_for_messages">
            <?php
                if(isset($_SESSION["error_messages"]) && !empty($_SESSION["error_messages"])){
                    echo $_SESSION["error_messages"];
                     //Уничтожаем ячейку error_messages, чтобы сообщения об ошибках не появились заново при обновлении страницы
                    unset($_SESSION["error_messages"]);
                }
                if(isset($_SESSION["success_messages"]) && !empty($_SESSION["success_messages"])){
                    echo $_SESSION["success_messages"];
                    
                    //Уничтожаем ячейку success_messages, чтобы сообщения не появились заново при обновлении страницы
                    unset($_SESSION["success_messages"]);
                }
            ?>
        </div>
    

Дальше, выведем форму, которая попросит пользователя ввести свой почтовый адрес. Эту форму мы будем вывести только для не авторизованных пользователей. То есть если пользователь уже авторизован, и он напрямую зайдёт на страницу " site.ru/reset_password.php " то он получить сообщение о том, что он уже авторизован.

Условие "if(!isset($_GET["hidden_form"]))", нужно для того чтобы спрятать эту форму после её успешной обработки. Вместо этой формы мы выведем какое-то сообщение.

        
        <?php 
            //Проверяем, если пользователь не авторизован, то выводим форму регистрации, 
            //иначе выводим сообщение о том, что он уже зарегистрирован
            if((!isset($_SESSION["email"]) && !isset($_SESSION["password"]))) {
                if(!isset($_GET["hidden_form"])){
        ?>
        
                    <div class="center_block">
                        <h2>Восстановление пароля</h2>
                        
                        <!-- Абзац -->
                        <p class="text_center mesage_error" id="valid_email_message"></p>
                        <form action="send_link_reset_password.php" method="post" name="form_request_email" >
                            <table>
                                <tr>
                                    <td> Введите Ваш <br />E-mail: </td>
                                    <td>
                                        <input type="email" name="email" placeholder="" >
                                    </td>
                                </tr>
                                <tr>
                                    <td> Введите капчу: </td>
                                    <td>
                                        <p>
                                            <img src="captcha.php" alt="Капча" /> <br />
                                            <input type="text" name="captcha" placeholder="Проверочный код" />
                                        </p>
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="2" class="text_center">
                                        <input type="submit" name="send" value="Восстановить">
                                    </td>
                                </tr>
                            </table>
                        </form>
                    </div>

        <?php 
                }//закрываем условие hidden_form

            }else{
        ?>
                <div id="authorized">
                    <h2>Вы уже авторизованы</h2>
                </div>
        <?php
            }

            //Подключение подвала
            require_once("footer.php");
        ?>
    

Идём в браузер, заходим на страницу авторизации, нажимаем на ссылку " забыли пароль " и смотрим, что у нас получилось.

Форма восстановления пароля

Обработка формы восстановления пароля

Обращаем внимание на значение атрибута " action " формы восстановления пароля. В нём мы указали файл " send_link_reset_password.php ".

Соответственно нам нужно создать этот файл и приступить к написанию кода для обработки данной формы.

Добавляем новое поле в таблицу users

Но, перед тем как продолжить нам нужно в таблицу " users ", добавить поле " reset_password_token " . Это поле нужно для сохранения токена. Токен это некий код. Для чего он нужен, Вы поймёте ниже.

Заходим в phpMyAdmin, открываем таблицу " users ", и кликаем на вкладке " структура ". Выбираем радио-кнопку " После ", из выпадающего списка выбираем поле " password " и нажимаем на кнопку ОК.

изменяем структуру таблицы users

После нажатия на кнопку OK, откроется следующее окно, где нужно будет ввести необходимые данные.

Добавление нового поля в таблицу users

После того как ввели необходимые данные, нажимаем на кнопку " сохранить ".

Всё, поле " reset_password_token ", добавили. Идём дальше.

Открываем созданный файл " send_link_reset_password.php " и пишем код.

        <?php
            //Запускаем сессию
            session_start();

            //Добавляем файл подключения к БД
            require_once("dbconnect.php");

            //Объявляем ячейку для добавления ошибок, которые могут возникнуть при обработке формы.
            $_SESSION["error_messages"] = '';

            //Объявляем ячейку для добавления успешных сообщений
            $_SESSION["success_messages"] = '';

            //Если кнопка Восстановить была нажата
            if(isset($_POST["send"])){

                //Проверяем, отправлена ли капча
                if(isset($_POST["captcha"])){
                    
                    //(1) Место для следующего куска кода
    
                }else{ //if(isset($_POST["captcha"]))
                    //Если капча не передана
                    exit("<p><strong>Ошибка!</strong> Отсутствует проверочный код, то есть код капчи. Вы можете перейти на <a href=".$address_site."> главную страницу </a>.</p>");
                }

            }else{ //if(isset($_POST["send"]))
                exit("<p><strong>Ошибка!</strong> Вы зашли на эту страницу напрямую, поэтому нет данных для обработки. Вы можете перейти на <a href=".$address_site."> главную страницу </a>.</p>");
            }
        ?>
    

Дальше мы должны проверить капчу и обработать полученный почтовый адрес. В указанное место " //(1) Место для следующего куска кода " пишем следующий код:

         
         //Обрезаем пробелы с начала и с конца строки
         $captcha = trim($_POST["captcha"]);

         if(!empty($captcha)){

             //Сравниваем полученное значение со значением из сессии. 
             if(($_SESSION["rand"] != $captcha) && ($_SESSION["rand"] != "")){
                 
                 // Если капча не верна, то возвращаем пользователя на страницу восстановления пароля, и там выведем ему сообщение об ошибке что он ввёл неправильную капчу.
                 
                 // Сохраняем в сессию сообщение об ошибке. 
                 $_SESSION["error_messages"] =  "<p class='mesage_error'><strong>Ошибка!</strong> Вы ввели неправильную капчу </p>";
                 
                 //Возвращаем пользователя на страницу восстановления пароля
                 header("HTTP/1.1 301 Moved Permanently");
                 header("Location: ".$address_site."reset_password.php");
                 //Останавливаем скрипт
                 exit();
             }
         }else{

             // Сохраняем в сессию сообщение об ошибке. 
             $_SESSION["error_messages"] = "<p class='mesage_error'><strong>Ошибка!</strong> Поле для ввода капчи не должна быть пустой. </p>";

             //Возвращаем пользователя на страницу восстановления пароля
             header("HTTP/1.1 301 Moved Permanently");
             header("Location: ".$address_site."reset_password.php");
             //Останавливаем скрипт
             exit();
         }


         //Обрабатываем полученный почтовый адрес
         if(isset($_POST["email"])){

             //Обрезаем пробелы с начала и с конца строки
             $email = trim($_POST["email"]);

             if(!empty($email)){

                 $email = htmlspecialchars($email, ENT_QUOTES);

                 //Проверяем формат полученного почтового адреса с помощью регулярного выражения
                 $reg_email = "/^[a-z0-9][a-z0-9\._-]*[a-z0-9]*@([a-z0-9]+([a-z0-9-]*[a-z0-9]+)*\.)+[a-z]+/i";

                 //Если формат полученного почтового адреса не соответствует регулярному выражению
                 if( !preg_match($reg_email, $email)){

                     // Сохраняем в сессию сообщение об ошибке. 
                     $_SESSION["error_messages"] = "<p class='mesage_error' >Вы ввели неправильный email</p>";
                     
                     //Возвращаем пользователя на страницу восстановления пароля
                     header("HTTP/1.1 301 Moved Permanently");
                     header("Location: ".$address_site."reset_password.php");

                     //Останавливаем скрипт
                     exit();
                 }
             }else{
                 // Сохраняем в сессию сообщение об ошибке. 
                 $_SESSION["error_messages"] = "<p class='mesage_error' > <strong>Ошибка!</strong> Поле для ввода почтового адреса(email) не должна быть пустой.</p>";
                 
                 //Возвращаем пользователя на страницу восстановления пароля
                 header("HTTP/1.1 301 Moved Permanently");
                 header("Location: ".$address_site."reset_password.php");
                 //Останавливаем скрипт
                 exit();
             }
             
         }else{
             // Сохраняем в сессию сообщение об ошибке. 
             $_SESSION["error_messages"] = "<p class='mesage_error' > <strong>Ошибка!</strong> Отсутствует поле для ввода Email</p>";
             
             //Возвращаем пользователя на страницу восстановления пароля
             header("HTTP/1.1 301 Moved Permanently");
             header("Location: ".$address_site."reset_password.php");

             //Останавливаем скрипт
             exit();
         }

         // (2) Место для составления запроса к БД
    

После успешной обработки капчи и полученного почтового адреса, мы должны сделать запрос к базе данных, для того чтобы проверить зарегистрирован ли у нас такой пользователь, и подтверждён ли указанный почтовый адрес.

В указанное место " // (2) Место для составления запроса к БД ", пишем следующий код:

        //Запрос к БД на выборке пользователя.
        $result_query_select = $mysqli->query("SELECT email_status FROM `users` WHERE email = '".$email."'");

        if(!$result_query_select){
            
            // Сохраняем в сессию сообщение об ошибке. 
            $_SESSION["error_messages"] = "<p class='mesage_error' > Ошибка запроса на выборки пользователя из БД</p>";
            
            //Возвращаем пользователя на страницу восстановления пароля
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."reset_password.php");

            //Останавливаем скрипт
            exit();

        }else{

            //Проверяем, если в базе нет пользователя с такими данными, то выводим сообщение об ошибке
            if($result_query_select->num_rows == 1){

                //Проверяем, подтвержден ли указанный email
                while(($row = $result_query_select->fetch_assoc()) !=false){

                    // (3) Место для следующего куска кода

                } // End while

            }else{
                
                // Сохраняем в сессию сообщение об ошибке. 
                $_SESSION["error_messages"] = "<p class='mesage_error' ><strong>Ошибка!</strong> Такой пользователь не зарегистрирован</p>";
                
                //Возвращаем пользователя на страницу восстановления пароля
                header("HTTP/1.1 301 Moved Permanently");
                header("Location: ".$address_site."reset_password.php");

                //Останавливаем скрипт
                exit();
            }
        }
    

Зарегистрирован ли у нас такой пользователь, мы проверили, теперь проверим, подтверждён ли указанный почтовый адрес. В указанное место " // (3) Место для следующего куска кода ", пишем следующий код:

        //Если email не подтверждён
        if((int)$row["email_status"] === 0){

            // Сохраняем в сессию сообщение об ошибке. 
            $_SESSION["error_messages"] = "<p class='mesage_error' ><strong>Ошибка!</strong> Вы не можете восстановить свой пароль, потому что указанный адрес электронной почты ($email) не подтверждён. </p><p>Для подтверждения почты перейдите по ссылке из письма, которую получили после регистрации.</p><p><strong>Внимание!</strong> Ссылка для подтверждения почты, действительна 24 часа с момента регистрации. Если Вы не подтвердите Ваш email в течении этого времени, то Ваш аккаунт будет удалён.</p>";
            
            //Возвращаем пользователя на страницу восстановления пароля
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."reset_password.php");

            //Останавливаем скрипт
            exit();

        }else{
            //Составляем зашифрованный и уникальный token
            $token=md5($email.time());

            //Сохраняем токен в БД
            $query_update_token = $mysqli->query("UPDATE users SET reset_password_token='$token' WHERE email='$email'");

            if(!$query_update_token){

                // Сохраняем в сессию сообщение об ошибке. 
                $_SESSION["error_messages"] = "<p class='mesage_error' >Ошибка сохранения токена</p><p><strong>Описание ошибки</strong>: ".$mysqli->error."</p>";
                
                //Возвращаем пользователя на страницу восстановления пароля
                header("HTTP/1.1 301 Moved Permanently");
                header("Location: ".$address_site."reset_password.php");

                //Останавливаем  скрипт
                exit();

            }else{

                //Составляем ссылку на страницу установки нового пароля.
                $link_reset_password = $address_site."set_new_password.php?email=$email&token=$token";

                 //Составляем заголовок письма
                 $subject = "Восстановление пароля от сайта ".$_SERVER['HTTP_HOST'];

                 //Устанавливаем кодировку заголовка письма и кодируем его
                 $subject = "=?utf-8?B?".base64_encode($subject)."?=";

                 //Составляем тело сообщения
                 $message = 'Здравствуйте! <br/> <br/> Для восстановления пароля от сайта <a href="http://'.$_SERVER['HTTP_HOST'].'"> '.$_SERVER['HTTP_HOST'].' </a>, перейдите по этой <a href="'.$link_reset_password.'">ссылке</a>.';
                 
                 //Составляем дополнительные заголовки для почтового сервиса mail.ru
                 //Переменная $email_admin, объявлена в файле dbconnect.php
                 $headers = "FROM: $email_admin\r\nReply-to: $email_admin\r\nContent-type: text/html; charset=utf-8\r\n";
                 
                 //Отправляем сообщение с ссылкой на страницу установки нового пароля и проверяем отправлена ли она успешно или нет. 
                 if(mail($email, $subject, $message, $headers)){

                     $_SESSION["success_messages"] = "<p class='success_message' >Ссылка на страницу установки нового пароля, была отправлена на указанный E-mail ($email) </p>";

                     //Отправляем пользователя на страницу восстановления пароля и убираем форму для ввода email
                     header("HTTP/1.1 301 Moved Permanently");
                     header("Location: ".$address_site."reset_password.php?hidden_form=1");

                     exit();

                 }else{
                     $_SESSION["error_messages"] = "<p class='mesage_error' >Ошибка при отправлении письма на почту ".$email.", с сылкой на страницу установки нового пароля. </p>";

                     //Возвращаем пользователя на страницу восстановления пароля
                     header("HTTP/1.1 301 Moved Permanently");
                     header("Location: ".$address_site."reset_password.php");
                     
                     //Останавливаем скрипт
                     exit();
                 }
             }
        } // if($row["email_status"] === 0)
    

Если указанный почтовый адрес не подтверждён, то мы в сессию добавляем сообщение об ошибке и перенаправляем пользователя обратно на страницу восстановления пароля.

Почтовый адрес не подтверждён

Иначе, мы составляем токен, добавляем его в базу данных, в поле " reset_password_token " таблицы " users " и отправляем пользователю письмо со ссылкой на страницу установки нового пароля.

отправление письма для установки нового пароля

Как видите из представленного кода, ссылка получает параметры email и токен, а формируется она следующим образом:

        //Составляем ссылку на страницу установки нового пароля.
        $link_reset_password = $address_site."set_new_password.php?email=$email&token=$token";
    

Посмотрим на содержание полученного письма:

Письмо с ссылкой на страницу установки нового пароля

И так, как мы видим, письмо отправилось успешно. С этим этапом мы закончили.

Установка нового пароля

В письме, если наведём мышку на ссылку, то, заметим что в левом нижнем углу появиться адрес данной ссылки. Из этого адреса, мы видим, что ссылка введёт на файл " set_new_password.php ".

Данный файл будет отвечать за вывод страницы установки нового пароля. То есть, с помощью этого файла, мы выведем форму, через которую пользователь сможет установить новый пароль.

Создаём этот файл " set_new_password.php ", открываем его и пишем следующий код:

        <?php 
        //Добавляем файл подключения к БД
        require_once("dbconnect.php");

        //Проверяем, если существует переменная token в глобальном массиве GET
        if(isset($_GET['token']) && !empty($_GET['token'])){
            $token = $_GET['token'];
        }else{
            exit("<p><strong>Ошибка!</strong> Отсутствует проверочный код.</p>");
        }

        //Проверяем, если существует переменная email в глобальном массиве GET
        if(isset($_GET['email']) && !empty($_GET['email'])){
            $email = $_GET['email'];
        }else{
            exit("<p><strong>Ошибка!</strong> Отсутствует адрес электронной почты.</p>");
        }
    

Здесь мы проверяем, существуют ли параметры token и email в ссылке, если они существуют, то идём дальше, иначе, выводим сообщение об ошибке. Вы можете сделать так чтобы, в случае ошибки, пользователя перенаправили на главную страницу.

Дальше нам нужно проверить, совпадает ли токен из ссылки с токеном из базы данных. Если токены совпадают, то выводим форму установки нового пароля, иначе, выводим сообщение об ошибке.

        //Делаем запрос на выборке токена из таблицы confirm_users
        $query_select_user = $mysqli->query("SELECT reset_password_token FROM `users` WHERE `email` = '".$email."'");
        //Если ошибок в запросе нет
        if(($row = $query_select_user->fetch_assoc()) != false){
            
            //Если такой пользователь существует
            if($query_select_user->num_rows == 1){
                //Проверяем совпадает ли token
                if($token == $row['reset_password_token']){

                    //(1) Место для вывода формы установки нового пароля

                }else{
                    exit("<p><strong>Ошибка!</strong> Неправильный проверочный код.</p>");
                }
            }else{
                exit("<p><strong>Ошибка!</strong> Такой пользователь не зарегистрирован </p>");
            }
        }else{
            //Иначе, если есть ошибки в запросе к БД
            exit("<p><strong>Ошибка!</strong> Сбой при выборе пользователя из БД. </p>");
        }

        // Завершение запроса выбора пользователя из таблицы users
        $query_select_user->close();

        //Закрываем подключение к БД
        $mysqli->close();
        ?>
    

В указанное место " //(1) Место для вывода формы установки нового пароля ", подключаем шапку и подвал, добавляем блок JavaScript кода и выводим форму установки нового пароля.

    
                    //Подключение шапки
                    require_once("header.php");
        ?>

                    
                    


                    <div class="center_block">
                                            
                        <h2>Установка нового пароля</h2>
                        
                        <!-- Форма установки нового пароля -->
                        <form action="update_password.php" method="post">
                            <table>
                                <tr>
                                    <td> Введите новый пароль: </td>
                                    <td>
                                        <input type="password" name="password" placeholder="минимум 6 символов" required="required" /><br />
                                        <span id="valid_password_message" class="mesage_error"></span>
                                    </td>
                                </tr>
                                <tr>
                                    <td> Повторите пароль: </td>
                                    <td>
                                        <input type="password" name="confirm_password" placeholder="минимум 6 символов" required="required" /><br />
                                        <span id="valid_confirm_password_message" class="mesage_error"></span>
                                    </td>
                                </tr>
                                <tr>
                                    <td colspan="2">
                                        <input type="hidden" name="token" value="<?=$token?>">
                                        <input type="hidden" name="email" value="<?=$email?>">
                                        <input type="submit" name="set_new_password" value="Изменить пароль" />
                                    </td>
                                </tr>
                            </table>
                        </form>
                    </div>
        <?php
                    //Подключение подвала
                    require_once("footer.php");

    

В итоге, у нас получилась вот такая страничка:

страница установки нового пароля

JavaScript код, нужен для того чтобы проверить длину вводимого пароля, и совпадает ли пароль из поля " Повторите пароль " с паролем из поле " Введите новый пароль ".

Обработка формы установки нового пароля

Как Вы заметили, в значение атрибута " action " указан файл " update_password.php ". С помощью этого файла мы обработаем форму установки нового пароля. То есть, обновим пароль в базе данных, у указанного пользователя.

Создаём этот файл " update_password.php " и пишем следующий код:

        <?php
            
            //Запускаем сессию
            session_start();
            
            //Добавляем файл подключения к БД
            require_once("dbconnect.php");

            if(isset($_POST["set_new_password"]) && !empty($_POST["set_new_password"])){
                
                //(1) Место для следующего куска кода

            }else{
                exit("<p><strong>Ошибка!</strong> Вы зашли на эту страницу напрямую, поэтому нет данных для обработки. Вы можете перейти на <a href=".$address_site."> главную страницу </a>.</p>");
            }
        ?>
    

Здесь мы проверяем, была ли нажата кнопка " Изменить пароль ".

Как Вы заметили, мы обработчику передаём скрытно токен и email. Токен здесь нужен для того чтобы мы смогли возвращаться обратно на страницу установки нового пароля, в случае какой-то ошибки, которая может возникнуть при обработке формы. То есть для того чтобы возвращаться из обработчика обратно на страницу установки нового пароля, нам нужно в ссылку передать токен и email.

Поэтому в обработчике, мы должны проверить существуют ли эти данные в массиве POST. Также мы должны обработать полученный пароль.

В указанное место " //(1) Место для следующего куска кода ", пишем следующий код:

        
        //Проверяем, если существует переменная token в глобальном массиве POST
        if(isset($_POST['token']) && !empty($_POST['token'])){
            $token = $_POST['token'];

        }else{

            // Сохраняем в сессию сообщение об ошибке. 
            $_SESSION["error_messages"] = "<p class='mesage_error' ><strong>Ошибка!</strong> Отсутствует проверочный код ( Передаётся скрытно ).</p>";
            
            //Возвращаем пользователя на страницу установки нового пароля
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."set_new_password.php?email=$email&token=$token");
            //Останавливаем  скрипт
            exit();
        }

        //Проверяем, если существует переменная email в глобальном массиве POST
        if(isset($_POST['email']) && !empty($_POST['email'])){
            $email = $_POST['email'];

        }else{
            // Сохраняем в сессию сообщение об ошибке. 
            $_SESSION["error_messages"] = "<p class='mesage_error' ><strong>Ошибка!</strong> Отсутствует адрес электронной почты ( Передаётся скрытно ).</p>";
            
            //Возвращаем пользователя на страницу установки нового пароля
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."set_new_password.php?email=$email&token=$token");
            //Останавливаем  скрипт
            exit();
        }

        if(isset($_POST["password"])){

            //Обрезаем пробелы с начала и с конца строки
            $password = trim($_POST["password"]);

            //Проверяем, совпадают ли пароли
            if(isset($_POST["confirm_password"])){

                //Обрезаем пробелы с начала и с конца строки
                $confirm_password = trim($_POST["confirm_password"]);

                if($confirm_password != $password){
                    // Сохраняем в сессию сообщение об ошибке. 
                    $_SESSION["error_messages"] = "<p class='mesage_error' >Пароли не совпадают</p>";
                    
                    //Возвращаем пользователя на страницу установки нового пароля
                    header("HTTP/1.1 301 Moved Permanently");
                    header("Location: ".$address_site."set_new_password.php?email=$email&token=$token");

                    //Останавливаем  скрипт
                    exit();
                }
            }else{
                // Сохраняем в сессию сообщение об ошибке. 
                $_SESSION["error_messages"] = "<p class='mesage_error' >Отсутствует поле для повторения пароля</p>";
                
                //Возвращаем пользователя на страницу установки нового пароля
                header("HTTP/1.1 301 Moved Permanently");
                header("Location: ".$address_site."set_new_password.php?email=$email&token=$token");

                //Останавливаем  скрипт
                exit();
            }

            if(!empty($password)){

                $password = htmlspecialchars($password, ENT_QUOTES);

                //Шифруем папроль
                $password = md5($password."top_secret"); 

            }else{

                // Сохраняем в сессию сообщение об ошибке. 
                $_SESSION["error_messages"] = "<p class='mesage_error' >Пароль не может быть пустым</p>";
                
                //Возвращаем пользователя на страницу установки нового пароля
                header("HTTP/1.1 301 Moved Permanently");
                header("Location: ".$address_site."set_new_password.php?email=$email&token=$token");
                //Останавливаем  скрипт
                exit();
            }

        }else{
            // Сохраняем в сессию сообщение об ошибке. 
            $_SESSION["error_messages"] = "<p class='mesage_error' >Отсутствует поле для ввода пароля</p>";
            
            //Возвращаем пользователя на страницу установки нового пароля
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."set_new_password.php?email=$email&token=$token");

            //Останавливаем  скрипт
            exit();
        }
        
        //(2) Место для следующего куска кода
    

Теперь, после успешной обработки полученных данных, настало время, обновить пароль у указанного пользователя.

В указанное место " //(2) Место для следующего куска кода ", пишем следующий код:

        $query_update_password = $mysqli->query("UPDATE users SET password='$password' WHERE email='$email'");

        if(!$query_update_password){

            // Сохраняем в сессию сообщение об ошибке. 
            $_SESSION["error_messages"] = "<p class='mesage_error' >Возникла ошибка при изменении пароля.</p><p><strong>Описание ошибки</strong>: ".$mysqli->error."</p>";
            
            //Возвращаем пользователя на страницу установки нового пароля
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."set_new_password.php?email=$email&token=$token");

            //Останавливаем  скрипт
            exit();

        }else{
            //Подключение шапки
            require_once("header.php");

            //Выводим сообщение о том, что пароль установлен успешно.
            echo '<h1 class="success_message text_center">Пароль успешно изменён!</h1>';
            echo '<p class="text_center">Теперь Вы можете войти в свой аккаунт.</p>';
            
            //Подключение подвала
            require_once("footer.php");
        }
    

Если пароль был изменён успешно, без ошибок, то мы увидим соответствующее сообщение:

пароль успешно изменён

На этом всё дорогие читатели, с реализации функционала восстановления пароля мы закончили. Но, перед тем как завершить данную статью, хочу Вам показать ещё один способ восстановления пароля.

Данный способ проще в реализации, но он имеет один небольшой недостаток. Я его Вам показываю только для того чтобы Вы знали что существует и такой вариант реализации. В чем его недостаток описано ниже.

Простой способ восстановления пароля

Данный способ отличается от предыдущего тем, что на указанную почту отправляется не ссылка на страницу установки нового пароля, а уже сгенерированный пароль.

Здесь также необходимо добавить ссылку " Забыли пароль ", при нажатии на которой попадаем на страницу где нужно ввести почтовый адрес. В предыдущем способе, за эту страницу отвечал файл " reset_password.php ". Можно его взять оттуда, потому что он будет такой же и в этом способе.

После того как пользователь ввёл свой адрес электронной почты и нажал на кнопку " Восстановить ", мы на указанный адрес отправим новый сгенерированный пароль.

За обработку формы восстановления пароля, из файла " reset_password.php ", у нас будет отвечать файл " send_new_password.php ", поэтому в значение атрибута " action ", у формы, напишем название этого файла. Создаём данный файл, открываем его и читаем дальше :).

Код данного файла, очень похож на код файла " send_link_reset_password.php ", за исключением некоторых строк. Поэтому копируем весь код файла " send_link_reset_password.php ", и вставляем его в файл " send_new_password.php ". Изменения нужно внести внутри блока else, который находится внутри цикла while.

        
        ............................................

        //Проверяем, подтвержден ли указанный email
        while(($row = $result_query_select->fetch_assoc()) !=false){
            
            //Если email не подтверждён
            if((int)$row["email_status"] == 0){

                // Сохраняем в сессию сообщение об ошибке. 
                $_SESSION["error_messages"] = "<p class='mesage_error' ><strong>Ошибка!</strong> Вы не можете восстановить свой пароль, потому что указанный адрес электронной почты ($email) не подтверждён. </p><p>Для подтверждения почты перейдите по ссылке из письма, которую получили после регистрации.</p><p><strong>Внимание!</strong> Ссылка для подтверждения почты, действительна 24 часа с момента регистрации. Если Вы не подтвердите Ваш email в течении этого времени, то Ваш аккаунт будет удалён.</p>";

                
                //Возвращаем пользователя на страницу авторизации
                header("HTTP/1.1 301 Moved Permanently");
                header("Location: ".$address_site."reset_password.php");

                //Останавливаем скрипт
                exit();
            }else{
                
                //Место, где нужно произвести изменения

            }
        }

        ............................................

    

Значит в указанное место " Место, где нужно произвести изменения " пишем следующий код:

        //Генерируем новый пароль. Берем последние 7 символов из хэша.
        $new_password = substr(md5($email.time()), -7);

        //Обновляем пароль в БД.
        $result_query_insert_password = $mysqli->query("UPDATE `users` SET `password` = '".md5($new_password."top_secret")."' WHERE email = '".$email."'");

        //Составляем заголовок письма
        $subject = "Восстановление пароля от сайта ".$_SERVER['HTTP_HOST'];

        //Устанавливаем кодировку заголовка письма и кодируем его
        $subject = "=?utf-8?B?".base64_encode($subject)."?=";

        //Составляем тело сообщения
        $message = 'Здравствуйте! <br/> <br/> Ваш новый пароль от сайта '.$_SERVER['HTTP_HOST'].' : '.$new_password;
        
        //Составляем дополнительные заголовки для почтового сервиса mail.ru
        //Переменная $email_admin, объявлена в файле dbconnect.php
        $headers = "FROM: $email_admin\r\nReply-to: $email_admin\r\nContent-type: text/html; charset=utf-8\r\n";
        
        //Отправляем сообщение с ссылкой для подтверждения регистрации на указанную почту и проверяем отправлена ли она успешно или нет. 
        if(mail($email, $subject, $message, $headers)){

            $_SESSION["success_messages"] = "<p class='success_message' >Новый пароль сгенерирован и отправлен на указанный E-mail ($email) </p>";

            //Отправляем пользователя на страницу регистрации и убираем форму регистрации
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."reset_password.php?hidden_form=1");
            exit();

        }else{

            $_SESSION["error_messages"] = "<p class='mesage_error' >Ошибка при отправки письма с новым паролем, на почту ".$email." </p>";

            //Возвращаем пользователя на страницу авторизации
            header("HTTP/1.1 301 Moved Permanently");
            header("Location: ".$address_site."reset_password.php");

            //Останавливаем скрипт
            exit();
        }
    

Здесь мы генерируем новый пароль, то есть берем последние 7 символов из хэша, который формируется за счёт указанного email и текущего времени. Обновляем пароль в базе данных для указанного пользователя. И на указанный почтовый адрес отправляем письмо с новым паролем.

отправление нового пароля

На указанный почтовый адрес, придёт такое письмо:

Письмо для восстановления пароля

И всё, пароль восстановлен. Теперь пользователь может авторизоваться со своим новым паролем.

В чем недостаток данного способа?

А недостаток здесь в том что, злоумышленник или любой другой пользователь может ввести email какого-то другого зарегистрированного пользователя и автоматически изменить его пароль.

Согласитесь, что зарегистрированный пользователь сильно удивится, что его пароль, внезапно изменился. Конечно, потери не критичны, но всё-таки это неприятно.

И здесь я завершаю свою статью. Теперь Вы знаете, как реализовать функционал восстановления пароля двумя способами, и можете использовать эти способы реализации в своих проектах.

Замечание! После скачивания архива с исходными файлами статьи, не забудьте поменять данные для подключения к базе данных и указать адрес Вашего сайта. Всё это нужно сделать в файле dbconnect.php.

Желаю хорошего дня и отличного настроения!

Видео прикол по теме:

Понравилась статья?

Тогда поделитесь ею с друзьями и подпишитесь на новые интересные статьи.

Поделиться с друзьями:

Подписаться на новые статьи:

Delivered by FeedBurner

Поддержите пожалуйста мой проект!

<< Предыдущая статьяСледующая статья >>

Если у Вас есть какие-то вопросы или предложения, то можете писать их в комментариях или мне на почту sergiu1607@gmail.com. И если Вы заметили какую-то ошибку в статье, то прошу Вас, сообщите мне об этом, и в ближайшее время я всё исправлю.

Добавляйтесь ко мне в друзья в:

Добавляйтесь в мои группы:

Подпишитесь на мои каналы:

Автор статьи: Мунтян Сергей

Копирование материалов с сайта sozdatisite.ru ЗАПРЕЩЕНО!!!

Дата добавления: 2017-07-24 01:11:09