Восстановлени пароля пользователя php + mysq

Восстановлени пароля пользователя php + mysq

Восстановлени пароля пользователя php + mysq

Привет друзья. В самом начале создания своего блога я написал статью как создать регистрацию и авторизацию на PHP + MySQL. Данная статья стала очень актуальной на моем блоге и требует своего логического продолжения, а именно это восстановление пароля пользователя. Ища информацию на просторах Рунета вы много найдете статей как создать регистрацию и авторизацию пользователей на сайте, но при этом все опускают тот момент, когда пользователь забыл свой пароль. В данной статье мы исправим этот досадный момент.

Восстановление пароля пользователя может быть двух способов:

  • Когда пароль в базе данных хранится не в зашифрованном виде, то вы можете выслать данный пароль пользователю на его email. (Хранить пароли в открытом виде очень небезопасно и так делать нельзя!).
  • Второй вариант, когда пароль хранится в зашифрованном виде, например, по средствам md5() и возможность дешифровать его нет. Тогда нужно создавать новый пароль и обновлять запись в таблице.

Рассмотрим структуру нашей таблицы:

Таблица bez_reg

У нас есть ID, есть логин, пароль в зашифрованном виде с солью, соль, active_hex и статус пользователя. Исходя из этих данных будем создавать алгоритм восстановления пароля на сайте. Особое внимание нужно уделить полю active_hex так как оно будет непосредственно участвовать в восстановлении пароля пользователя.

Сейчас попробуем описать алгоритм действий для реализации восстановления пароля пользователя на php + mysql.

  • Показываем форму с вводом логина для восстановления.
  • Если такой логин есть, то шлем ему письмо ссылкой и ключом в качестве ключа используем строку из ячейки active_hex.
  • Когда пользователь прошел по ссылке проверяем ключ, если ключ совпадает с полем active_hex то выводим форму с двумя полями для вода нового пароля. Как только пользователь сменил пароль, в целях безопасности генерируем новый active_hex, чтобы никто не смог воспользоваться ссылкой восстановления пароля повторно! Далее отправляем письмо о том, что пароль сменен и ссылку для входа.
  • Пользователь входит с новым паролем.

Я не буду здесь расписывать все скрипты, вы можете ознакомится с ними в первой статье регистрация и авторизация на PHP + MySQL. Здесь я выложу дополнения к данным скриптам.

В каталоге scripts создаем новую папку reminder. В данном каталоге создаем три файла:

  • form_reminder.html
  • new_pass_form.html
  • reminder.php

Структура каталогов регистрация и авторизация php + mysql

Далее переходим в index.php и подключаем наши файлы в switch();


<?php
    /**
    * Главный файл (переключатель)
    * Site: http://bezramok-tlt.ru
    * Регистрация пользователя письмом
    */

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

    //Устанавливаем кодировку и вывод всех ошибок
    header('Content-Type: text/html; charset=UTF8');
    error_reporting(E_ALL);

    //Включаем буферизацию содержимого
    ob_start();

    //Определяем переменную для переключателя
    $mode = isset($_GET['mode'])  ? $_GET['mode'] : false;
    $user = isset($_SESSION['user']) ? $_SESSION['user'] : false;
    $err = array();


    //Устанавливаем ключ защиты
    define('BEZ_KEY', true);
     
    //Подключаем конфигурационный файл
    include './config.php';
     
    //Подключаем скрипт с функциями
    include './func/funct.php';

    //подключаем MySQL
    include './bd/bd.php';

    switch($mode)
    {
        //Подключаем обработчик с формой регистрации
        case 'reg':
            include './scripts/reg/reg.php';
            include './scripts/reg/reg_form.html';
        break;
        
        //Подключаем обработчик с формой авторизации
        case 'auth':
            include './scripts/auth/auth.php';
            include './scripts/auth/auth_form.html';
            include './scripts/auth/show.php';
        break;

        //Восстановление пароля
        case 'reminder';
            include './scripts/reminder/reminder.php';
            //Выводим нужную форму для пользователя
            //Проверяем что ключ не проходит по ссылке после восстановления
            if(isset($_GET['key']))
            {
                //Проверяем есть ли такой ключ
                $sql = 'SELECT COUNT(*) AS `total`
                        FROM `'. BEZ_DBPREFIX .'reg`
                        WHERE `active_hex` = :active_hex';

                //Подготавливаем PDO выражение для SQL запроса
                $stmt = $db->prepare($sql);
                $stmt->bindValue(':active_hex', $_GET['key'], PDO::PARAM_STR);
                if($stmt->execute())
                {
                    $row = $stmt->fetch(PDO::FETCH_ASSOC);

                    //Проверяем что вернул запрос
                    if($row['total'] == 0)
                        include './scripts/reminder/form_reminder.html';
                    else
                    {
                        //Отправляем на главную страницу
                        //header('Location: '. BEZ_HOST);
                        //exit;
                        include './scripts/reminder/new_pass_form.html';
                    }
                }
            }
            else
            {
                if(!isset($_GET['newpass']))
                    include './scripts/reminder/form_reminder.html';
            //  include './scripts/reminder/new_pass_form.html';
            }
        break;
    
    }
    
    //Получаем данные с буфера
    $content = ob_get_contents();
    ob_end_clean();

    //Подключаем наш шаблон
    include './html/index.html';
?>
           

Создаем html разметку для формы восстановления пароля пользователя в файле form_reminder.html


<div class="col-md-8 col-md-offset-2"> 
<div class="panel panel-primary">
  <div class="panel-heading"><h4>Восстановление параметров авторизации</h4></div>
  <div class="panel-body">
    <p>Если забыли свои параметры авторизации, не переживайте, их можно восстановить. Для этого введите, пожалуйста, ниже свой email.</p>
    <form class="form-horizontal" action="" method="POST">
  <div class="form-group">
    <label for="inputEmail" class="col-xs-2 control-label">Адрес email:</label>
    <div class="col-xs-10">
     <input type="email" class="form-control" id="inputEmail" name="email" placeholder="Введите email">
    </div>
  </div>
 <div class="form-group">
    <div class="col-xs-offset-2 col-xs-10">
      <button type="submit" class="btn btn-primary" name="reminder">Восстановить</button>
   </div>
  </div>
</form>
  </div>
</div>
</div>

Далее создаем html разметку для ввода нового пароля пользователя в файле new_pass_form.html


<div class="col-md-8 col-md-offset-2"> 
<div class="panel panel-primary">
  <div class="panel-heading"><h4>Восстановление пароля</h4></div>
  <div class="panel-body">
    <form class="form-horizontal" action="" method="POST">
  <div class="form-group">
    <label for="inputPass" class="col-xs-2 control-label">Пароль:</label>
    <div class="col-xs-10">
     <input type="password" class="form-control" id="inputPass" name="pass" placeholder="Введите пароль">
    </div>
  </div>
    <div class="form-group">
    <label for="inputPass2" class="col-xs-2 control-label">Повторите пароль:</label>
    <div class="col-xs-10">
     <input type="password" class="form-control" id="inputPass2" name="pass2" placeholder="Введите подтверждение пароля">
    </div>
  </div>
 <div class="form-group">
    <div class="col-xs-offset-2 col-xs-10">
      <button type="submit" class="btn btn-primary" name="newPass">Изменить</button>
   </div>
  </div>
</form>
  </div>
</div>
</div>

Формы мы сделали, самое время написать обработчик данных форм reminder.php


<?php
 /**
 * Обработчик формы восстановления пароля
 * Site: http://bezramok-tlt.ru
 * Авторизация пользователя
 */

 //Ключ защиты
 if(!defined('BEZ_KEY'))
 {
     header("HTTP/1.1 404 Not Found");
     exit(file_get_contents('./../404.html'));
 }
 
 //Выводим сообщение об отправки ссылки для восстановления пароля
 if(isset($_GET['send']) and $_GET['send'] == 'ok')
    echo '<div class="alert alert-success"><h4 class="text-center">Ваш запрос на восстановление пароля отправлен на указаный вами email!</h4></div>';

  //Выводим сообщение об успешно смене пароля
  if(isset($_GET['newpass']) and $_GET['newpass'] == 'ok')
    echo '<div class="alert alert-success"><h4 class="text-center">Ваш пароль успешно изменен, проверьте свой email!</h4></div>';

 //Если нажата кнопка восстановить пароль утюжим переменные 
 if(isset($_POST['reminder'])){
    
    //Если email существует, то проверяем есть ли он в нашей базе
    if(emailValid($_POST['email'])){
        //Запрос на выборку аккаунта для восстановления
        $sql = 'SELECT * FROM `'. BEZ_DBPREFIX .'reg`
                WHERE `status` = 1
                AND `login` = :email';

        //Подготавливаем PDO выражение для SQL запроса
        $stmt = $db->prepare($sql);
        $stmt->bindValue(':email', $_POST['email'], PDO::PARAM_STR);
        if($stmt->execute())
        {
            //Получаем ответ от MySQL
            $rows = $stmt->fetch(PDO::FETCH_ASSOC);
            
            //Проверяем что такой email есть
            if(!empty($rows))
            {
                //Шлем письмо для восстановления пароля
                $title = 'Вы запросили восстановление пароля на http://bezramok-tlt.ru';
                $message = 'Для смены пароля Вам нужно пройти по ссылке <a href="'. BEZ_HOST .'?mode=reminder&key='. $rows['active_hex'] .'">'. BEZ_HOST .'?mode=reminder&key='. $rows['active_hex'] .'</a>';
                    
                sendMessageMail($_POST['email'], BEZ_MAIL_AUTOR, $title, $message);
                    
                //Перенаправляем пользователя на нужную нам страницу
                header('Location:'. BEZ_HOST .'?mode=reminder&send=ok');
                exit;
            }
            else
            {
                echo showErrorMessage('Нет такого пользователя!');
            }
        }
        else
        {
                echo showErrorMessage('Что-то пошло не так :(');
        }

    }
    else
    {
        echo showErrorMessage('Не верные данные!');
    }

}

 //Если пользователь сменил пароль
if(isset($_POST['newPass']))
{
    //Утюжим переменные
    if(empty($_POST['pass']))
        $err[] = 'Поле Пароль не может быть пустым';
    
    if(empty($_POST['pass2']))
        $err[] = 'Поле Подтверждения пароля не может быть пустым';
    
    //Проверяем равенство паролей
    if($_POST['pass'] != $_POST['pass2'])
        $err[] = 'Пароли не совпадают!';
    
    //Проверяем наличие ошибок и выводим пользователю
    if(count($err) > 0)
        echo showErrorMessage($err);
    else
    {
        //Получаем данные о пользователе
        $sql = 'SELECT * FROM `'. BEZ_DBPREFIX .'reg`
                WHERE `status` = 1
                AND `active_hex` = :active_hex';

        //Подготавливаем PDO выражение для SQL запроса
        $stmt = $db->prepare($sql);
        $stmt->bindValue(':active_hex', $_GET['key'], PDO::PARAM_STR);
        if($stmt->execute())
        {
            //Получаем ответ от MySQL
            $rows = $stmt->fetch(PDO::FETCH_ASSOC);
            
            //Почтовый ящик
            $email = $rows['login'];
            
            //Солим пароль
            $pass = md5(md5($_POST['pass']).$rows['salt']);
            
            //Создаем новый active_hex для защиты
            $active_hex = md5($pass);

            //Обновляем данные в таблице
            $sql = 'UPDATE `'. BEZ_DBPREFIX .'reg`
                SET 
                    `pass` = :pass, 
                    `active_hex` = :active_hex
                WHERE `id` = '. $rows['id'];
            
            //Подготавливаем PDO выражение для SQL запроса
            $stmt = $db->prepare($sql);
            
            //Если запрос выполнился
            if($stmt->execute(array(':pass' => $pass, ':active_hex' => $active_hex)))
            {
                //Отправляем сообщение на почту об успешной смене пароля
                $title = 'Вы успешно сменили пароль на http://bezramok-tlt.ru';
                $message = 'Вы успешно сменили пароль на '. $_POST['pass'] .'
                <p>для входа в систему перейдите по ссылке <a href="'. BEZ_HOST .'?mode=auth">'. BEZ_HOST .'?mode=auth</a></p>';
                        
                sendMessageMail($email, BEZ_MAIL_AUTOR, $title, $message);
                    
                //Перенаправляем пользователя на нужную нам страницу
                header('Location:'. BEZ_HOST .'?mode=reminder&newpass=ok');
                exit;
            }

        }
    }
    
}

?>

Как видите написание данного функционала совсем не сложное дело, проблема в том, что новички в программирование не могут выразить человеческим языком последовательность действий (алгоритма работы), тем самым и создаются трудности в написании того или иного скрипта. С вами был админ https://bezramok-tlt.ru до новых встреч друзья и удачного кодинга!

Архив перезолил: 02.02.2017г.

Скачать: Восстановлени пароля пользователя php + mysq


Теги

Поддержи проект:


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

02/10/2016 19:25:28

Администрация
Администрация

В шаблон добавь!  html\index.html

02/10/2016 19:28:59

...
я заметил
Еще вопрос как сделать что бы возле кнопки регистрация и вход, была надпись привет гость?  Еще вопрос как сделать что бы при входе пользователя исчезала форма регистрации и входа?

02/10/2016 16:33:15

Администрация
Администрация

Чтобы выводить логин пользователя нужно использовать сессии, пока пользователь не авторизовался он Гость, как только залогинелся в место дефолтного имени Гость подставляете значении залогиненого пользователя которое хранится у вас в сессии!

Чтобы форма исчезла нужно соответствующее условие. Подсказка используй сессии )

02/10/2016 17:25:22

...
я заметил
Отлично все стало на свои места, я в принципе правильно ставил только я еще добавлял строку, на проверку ошибок) получается 2 раза проверял наличии ошибок))) Админ спасибо)

02/10/2016 16:09:17

Администрация
Администрация

Не за что.

02/10/2016 17:19:45

...
я заметил
Понял какой код надо указать:  if($_POST['pass'] != $_POST['pass2']) $err[] = 'Пароли не совподают'; Только куда поставить не знаю!

02/10/2016 14:45:56

Администрация
Администрация
<?php
//Утюжим переменные
if(empty($_POST['pass']))
	$err[] = 'Поле Пароль не может быть пустым';

if(empty($_POST['pass2']))
	$err[] = 'Поле Подтверждения пароля не может быть пустым';

//Проверяем равенство паролей
if($_POST['pass'] != $_POST['pass2'])
	$err[] = 'Пароли не совподают!';
?>

02/10/2016 15:35:03

...
Bez_imen
Я уже разобрался в старом проекте делаю, только дописал все что указали в уроке, и все стало на свои места.

02/10/2016 14:19:31

Администрация
Администрация

Хорошо.

02/10/2016 14:30:29

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

02/10/2016 14:18:22

Администрация
Администрация

Да сейчас заметил нет проверки на равенство пароля. Вечером исправлю и перезалью.

02/10/2016 14:29:49

...
Bez_imen
Почему не работает? Админ перезалей

02/10/2016 13:40:46

Администрация
Администрация

Что не работает, пришли скрин на почту bezramok-tlt@mail.ru вечером гляну.

02/10/2016 14:10:00

...
Bez_imen
Отлично ADMIN спасибо, очень нужная вещь благодарю! Пошел исправлять не хватки этой функции))) еще раз спасибо респект.

01/10/2016 18:17:50

Администрация
Администрация

Не за что:)

02/10/2016 14:09:11


Copyright © 2014 - 2021 All rights reserved.