Защищенная Авторизация и Регистрация на PHP + MySQL через PDO

В этой статье Вы найдете скрипт на языке программирования PHP, который позволяет пользователю зарегистрироваться и авторизоваться на сайте.
Скрипт на 100% защищает от SQL-инжекций, поскольку использует PDO (система подготовленных запросов) и библиотеку RedBeanPHP, которая реализует ORM. Использовать
RedBeanPHP мы будем только, чтобы присоединиться к базе данных и легко ей манипулировать,
не используя стандартные команды в PHP, такие как mysql_connect и подобные, потому что они устаревшие и не очень эффективные.

Скрипт использует сессии ($_SESSION) и позволяет узнать авторизован сейчас человек или нет.
Также в скрипте предусмотрена капча с рандомными вопросами, которая защищает сайт от надоедливого спама.

Скрипт состоит из следующих файлов:

  • index.php — содержит 2 ссылки (на форму авторизации и регистрации);
  • rb.php — ORM-библиотека RedBeanPHP;
  • db.php — подключение к базе данных;
  • login.php — обработчик авторизации пользователя и форма авторизации;
  • signup.php — обработчик регистрации пользователя и форма регистрации;
  • logout.php — выход из сессии.

Как подключить скрипт?

Скачайте готовый скрипт и перенесите все файлы на свой хостинг или локальный сервер (Denwer, OpenServer). Для работы скрипта Вам потребуется версия PHP не ниже 5.6. Далее необходимо создать базу данных и подсоединиться к ней. Для этого потребуется поменять значения в файле db.php. Если с этим возникнут трудности, то Вы можете задавать свои вопросы в комментариях под статьей.


Форма авторизации

В файле login.php находится обработчик и сама форма авторизации, которая состоит из двух полей (логин, пароль). Значок @ (собачка) перед переменными служит в PHP для отключения ошибки, если такая возникнет.

<form action="login.php" method="POST">
	<strong>Логин</strong>
	<input type="text" name="login" value="<?php echo @$data['login']; ?>"><br/>

	<strong>Пароль</strong>
	<input type="password" name="password" value="<?php echo @$data['password']; ?>"><br/>

	<button type="submit" name="do_login">Войти</button>
</form>

PHP обработчик формы авторизации пользователя

Все переменные, которые возвращаются по методу POST — мы присваиваем переменной $data.

	$data = $_POST;
	if ( isset($data['do_login']) )
	{
		$user = R::findOne('users', 'login = ?', array($data['login']));
		if ( $user )
		{
			//логин существует
			if ( password_verify($data['password'], $user-&gt;password) )
			{
				//если пароль совпадает, то нужно авторизовать пользователя
				$_SESSION['logged_user'] = $user;
				echo '<div style="color:dreen;">Вы авторизованы!<br/> 
				Можете перейти на <a href="https://obninsksite.ru/">главную</a> страницу.</div><hr>';
			}else
			{
				$errors[] = 'Неверно введен пароль!';
			}

		}else
		{
			$errors[] = 'Пользователь с таким логином не найден!';
		}
		
		if ( ! empty($errors) )
		{
			//выводим ошибки авторизации
			echo '<div id="errors" style="color:red;">' .array_shift($errors). '</div><hr>';
		}

	}

Форма регистрации

В файле signup.php находится обработчик и сама форма регистрации. Для таких форм рекомендуется использовать метод запроса POST, при котором веб-сервер принимает данные, заключённые в тело сообщения, для хранения.

<form action="https://obninsksite.ru/signup.php" method="POST">
	<strong>Ваш логин</strong>
	<input type="text" name="login" value="<?php echo @$data['login']; ?>"><br/>

	<strong>Ваш Email</strong>
	<input type="email" name="email" value="<?php echo @$data['email']; ?>"><br/>

	<strong>Ваш пароль</strong>
	<input type="password" name="password" value="<?php echo @$data['password']; ?>"><br/>

	<strong>Повторите пароль</strong>
	<input type="password" name="password_2" value="<?php echo @$data['password_2']; ?>"><br/>

	<strong><?php captcha_show(); ?></strong>
	<input type="text" name="captcha"><br/>

	<button type="submit" name="do_signup">Регистрация</button>
</form>

PHP обработчик формы регистрации пользователя

	$data = $_POST;

	function captcha_show(){
		$questions = array(
			1 =&gt; 'Столица России',
			2 =&gt; 'Столица США',
			3 =&gt; '2 + 3',
			4 =&gt; '15 + 14',
			5 =&gt; '45 - 10',
			6 =&gt; '33 - 3'
		);
		$num = mt_rand( 1, count($questions) );
		$_SESSION['captcha'] = $num;
		echo $questions[$num];
	}

	//если кликнули на button
	if ( isset($data['do_signup']) )
	{
    // проверка формы на пустоту полей
		$errors = array();
		if ( trim($data['login']) == '' )
		{
			$errors[] = 'Введите логин';
		}

		if ( trim($data['email']) == '' )
		{
			$errors[] = 'Введите Email';
		}

		if ( $data['password'] == '' )
		{
			$errors[] = 'Введите пароль';
		}

		if ( $data['password_2'] != $data['password'] )
		{
			$errors[] = 'Повторный пароль введен не верно!';
		}

		//проверка на существование одинакового логина
		if ( R::count('users', "login = ?", array($data['login'])) &gt; 0)
		{
			$errors[] = 'Пользователь с таким логином уже существует!';
		}
    
    //проверка на существование одинакового email
		if ( R::count('users', "email = ?", array($data['email'])) &gt; 0)
		{
			$errors[] = 'Пользователь с таким Email уже существует!';
		}

		//проверка капчи
		$answers = array(
			1 =&gt; 'москва',
			2 =&gt; 'вашингтон',
			3 =&gt; '5',
			4 =&gt; '29',
			5 =&gt; '35',
			6 =&gt; '30'
		);
		if ( $_SESSION['captcha'] != array_search( mb_strtolower($_POST['captcha']), $answers ) )
		{
			$errors[] = 'Ответ на вопрос указан не верно!';
		}


		if ( empty($errors) )
		{
			//ошибок нет, теперь регистрируем
			$user = R::dispense('users');
			$user-&gt;login = $data['login'];
			$user-&gt;email = $data['email'];
			$user-&gt;password = password_hash($data['password'], PASSWORD_DEFAULT); 
			//пароль нельзя хранить в открытом виде, 
			//мы его шифруем при помощи функции password_hash для php &gt; 5.6
			
			R::store($user);
			echo '<div style="color:dreen;">Вы успешно зарегистрированы!</div><hr>';
		}else
		{
			echo '<div id="errors" style="color:red;">' .array_shift($errors). '</div><hr>';
		}

	}

Смотреть видеоурок

Статья была написана на основе видеоурока Хауди Хо, который Вы можете посмотреть ниже. Скрипт из видео был немного доработан (добавлена капча function captcha_show).