Языки программирования

Создание системы регистрации и авторизации на PHP

В этой статье мы создадим систему регистрации и авторизации. Что нам понадобиться для написания такой системы:
  1. Язык программирования PHP;
  2. Библиотека RedBeanPHP для соединения с базой данных;
  3. Язык гипертекстовой разметки (HTML);
  4. Каскадные стили таблиц (CSS);
  5. Фреймворк Bootstrap;
  6. Функции API для хеширования паролей;
  7. Локальный сервер XAMPP;

1. Создание базы данных

Создаем базу данных в интерфейсе «phpAdmin«. Базу данных называете как вам угодно, в «Сравнение» выбираем «utf8_general_ci»:
Таблицу создавать не надо, т.к. таблица будет создаваться при регистрации пользователя.

2. Соединение с базой данных

На локальном сервере XAMPP в папке «htdocs» создаем папку нашего будущего проекта. В этой папке создаем первый php файл «db.php». Он нужен для соединения с базой данных.
Так как мы будем пользоваться библиотекой RedBeanPHP, тогда надо скачать библиотеку и подключить к проекту. Мы создадим в папке проекта папку «libs» и туда закинем библиотеку. Листинг файла db.php:
<?php
// Подключаем библиотеку RedBeanPHP
require "libs/rb-mysql.php";

// Подключаемся к БД
R::setup( 'mysql:host=localhost;dbname=register',
        'root', '' );

// Проверка подключения к БД
if(!R::testConnection()) die('No DB connection!');

session_start(); // Создаем сессию для авторизации
?>
Имя пользователя для соединения c базой данных устанавливается по умолчанию (XAMPP), конечно если в phpMyAdmin вы их не меняли.

3. Создание шапки и подвала проекта

Создадим два файла и назовём их «header.php» и «footer.php». Мы их будем подключать к нашим будущим формам. В статье «PHP. Динамическое создание страниц» можно изучить для чего это необходимо. Листинг файла header.php:
<!DOCTYPE html>
<html lang="ru">
<head>
	<title><?php echo $title; ?></title>
	<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
	<link rel="stylesheet" type="text/css" href="css/style.css">
	<meta content="text/html; charset=utf-8">
</head>
<body>
Это обычная шапка проекта. Для подключения стилей создайте в проекте папку «css» и в ней создайте файл style.css, а также скачайте файл фреймворка Bootstrap и закиньте его в эту папку.

Переменная $title необходима для изменения названия страниц на разных формах (т.к. в проекте будет больше одной формы). Листинг файла footer.php:
</body>
</html>
Листинг файла style.css:
form, h2, p{
	width: 500px;
	margin-left: 300px;
}

4. Создание форм

С помощью HTML, CSS и Bootstrap создадим необходимые формы приложения. В папке проекта создаем форму регистрации. Файл назовём «signup.php». Листинг файла:
<?php 
$title="Форма регистрации"; // название формы
require __DIR__ . '/header.php'; // подключаем шапку проекта
require "db.php"; // подключаем файл для соединения с БД
?>

<div class="container mt-4">
		<div class="row">
			<div class="col">
	   <!-- Форма регистрации -->
		<h2>Форма регистрации</h2>
		<form action="signup.php" method="post">
			<input type="text" class="form-control" name="login" id="login" placeholder="Введите логин"><br>
			<input type="email" class="form-control" name="email" id="email" placeholder="Введите Email"><br>
			<input type="text" class="form-control" name="name" id="name" placeholder="Введите имя" required><br>
			<input type="text" class="form-control" name="family" id="family" placeholder="Введите фамилию" required><br>
			<input type="password" class="form-control" name="password" id="password" placeholder="Введите пароль"><br>
			<input type="password" class="form-control" name="password_2" id="password_2" placeholder="Повторите пароль"><br>
			<button class="btn btn-success" name="do_signup" type="submit">Зарегистрировать</button>
		</form>
		<br>
		<p>Если вы зарегистрированы, тогда нажмите <a href="login.php">здесь</a>.</p>
		<p>Вернуться на <a href="index.php">главную</a>.</p>
			</div>
		</div>
	</div>
<?php require __DIR__ . '/footer.php'; ?> <!-- Подключаем подвал проекта -->
Итоговый дизайн формы регистрации:
В папке проекта создаем форму авторизации. Файл назовём «login.php». Листинг файла:
<?php 
$title="Форма авторизации"; // название формы
require __DIR__ . '/header.php'; // подключаем шапку проекта
require "db.php"; // подключаем файл для соединения с БД
?>

<div class="container mt-4">
		<div class="row">
			<div class="col">
		<!-- Форма авторизации -->
		<h2>Форма авторизации</h2>
		<form action="login.php" method="post">
			<input type="text" class="form-control" name="login" id="login" placeholder="Введите логин" required><br>
			<input type="password" class="form-control" name="password" id="pass" placeholder="Введите пароль" required><br>
			<button class="btn btn-success" name="do_login" type="submit">Авторизоваться</button>
		</form>
		<br>
		<p>Если вы еще не зарегистрированы, тогда нажмите <a href="signup.php">здесь</a>.</p>
		<p>Вернуться на <a href="index.php">главную</a>.</p>
			</div>
		</div>
	</div>

<?php require __DIR__ . '/footer.php'; ?> <!-- Подключаем подвал проекта -->
Итоговый дизайн формы авторизации:
Формы будут обрабатываться с помощью метода POST. Обработка форм будет в файлах с формами.

5. Обработка формы регистрации

В файле «signup.php» после подключения файла с базой данных пишем код описанный ниже. Чтобы понять код читайте комментарии к нему. Листинг:
// Создаем переменную для сбора данных от пользователя по методу POST
$data = $_POST;

// Пользователь нажимает на кнопку "Зарегистрировать" и код начинает выполняться
if(isset($data['do_signup'])) {

        // Регистрируем
        // Создаем массив для сбора ошибок
	$errors = array();

	// Проводим проверки
        // trim — удаляет пробелы (или другие символы) из начала и конца строки
	if(trim($data['login']) == '') {

		$errors[] = "Введите логин!";
	}

	if(trim($data['email']) == '') {

		$errors[] = "Введите Email";
	}


	if(trim($data['name']) == '') {

		$errors[] = "Введите Имя";
	}

	if(trim($data['family']) == '') {

		$errors[] = "Введите фамилию";
	}

	if($data['password'] == '') {

		$errors[] = "Введите пароль";
	}

	if($data['password_2'] != $data['password']) {

		$errors[] = "Повторный пароль введен не верно!";
	}
         // функция mb_strlen - получает длину строки
        // Если логин будет меньше 5 символов и больше 90, то выйдет ошибка
	if(mb_strlen($data['login']) < 5 || mb_strlen($data['login']) > 90) {

	    $errors[] = "Недопустимая длина логина";

    }

    if (mb_strlen($data['name']) < 3 || mb_strlen($data['name']) > 50){
	    
	    $errors[] = "Недопустимая длина имени";

    }

    if (mb_strlen($data['family']) < 5 || mb_strlen($data['family']) > 50){
	    
	    $errors[] = "Недопустимая длина фамилии";

    }

    if (mb_strlen($data['password']) < 2 || mb_strlen($data['password']) > 8){
	
	    $errors[] = "Недопустимая длина пароля (от 2 до 8 символов)";

    }

    // проверка на правильность написания Email
    if (!preg_match("/[0-9a-z_]+@[0-9a-z_^\.]+\.[a-z]{2,3}/i", $data['email'])) {

	    $errors[] = 'Неверно введен е-mail';
    
    }

	// Проверка на уникальность логина
	if(R::count('users', "login = ?", array($data['login'])) > 0) {

		$errors[] = "Пользователь с таким логином существует!";
	}

	// Проверка на уникальность email

	if(R::count('users', "email = ?", array($data['email'])) > 0) {

		$errors[] = "Пользователь с таким Email существует!";
	}


	if(empty($errors)) {

		// Все проверено, регистрируем
		// Создаем таблицу users
		$user = R::dispense('users');

                // добавляем в таблицу записи
		$user->login = $data['login'];
		$user->email = $data['email'];
		$user->name = $data['name'];
		$user->family = $data['family'];

		// Хешируем пароль
		$user->password = password_hash($data['password'], PASSWORD_DEFAULT);

		// Сохраняем таблицу
		R::store($user);
        echo '<div style="color: green; ">Вы успешно зарегистрированы! Можно <a href="login.php">авторизоваться</a>.</div><hr>';

	} else {
                // array_shift() извлекает первое значение массива array и возвращает его, сокращая размер array на один элемент. 
		echo '<div style="color: red; ">' . array_shift($errors). '</div><hr>';
	}
}
Как видите наша регистрация безопасна на 100% т.к. есть множество различных проверок и хеширование пароля. Зарегистрировать двух пользователей с одинаковым логином и Email невозможно. Вы можете добавить и другие проверки при регистрации.

6. Обработка формы авторизации

В файле «login.php» после подключения файла с базой данных пишем код описанный ниже. Чтобы понять код читайте комментарии к нему. Листинг:
// Создаем переменную для сбора данных от пользователя по методу POST
$data = $_POST;

// Пользователь нажимает на кнопку "Авторизоваться" и код начинает выполняться
if(isset($data['do_login'])) { 

 // Создаем массив для сбора ошибок
 $errors = array();

 // Проводим поиск пользователей в таблице users
 $user = R::findOne('users', 'login = ?', array($data['login']));

 if($user) {

 	// Если логин существует, тогда проверяем пароль
 	if(password_verify($data['password'], $user->password)) {

 		// Все верно, пускаем пользователя
 		$_SESSION['logged_user'] = $user;
 		
 		// Редирект на главную страницу
                header('Location: index.php');

 	} else {
    
    $errors[] = 'Пароль неверно введен!';

 	}

 } else {
 	$errors[] = 'Пользователь с таким логином не найден!';
 }

if(!empty($errors)) {

		echo '<div style="color: red; ">' . array_shift($errors). '</div><hr>';

	}

}

7. Создание главного файла приложения

Все формы и обработчики форм мы написали, а теперь создадим главный файл где будет отображаться приветствие пользователя, когда он будет авторизован. Файл назовём «index.php». Листинг:
<?php
$title="Главная страница"; // название формы
require __DIR__ . '/header.php'; // подключаем шапку проекта
require "db.php"; // подключаем файл для соединения с БД
?>

<div class="container mt-4">
<div class="row">
<div class="col">
<center>
<h1>Добро пожаловать на наш сайт!</h1>
</center>
</div>
</div>
</div>

<!-- Если авторизован выведет приветствие -->
<?php if(isset($_SESSION['logged_user'])) : ?>
	Привет, <?php echo $_SESSION['logged_user']->name; ?></br>

<!-- Пользователь может нажать выйти для выхода из системы -->
<a href="logout.php">Выйти</a> <!-- файл logout.php создадим ниже -->
<?php else : ?>

<!-- Если пользователь не авторизован выведет ссылки на авторизацию и регистрацию -->
<a href="login.php">Авторизоваться</a><br>
<a href="signup.php">Регистрация</a>
<?php endif; ?>

<?php require __DIR__ . '/footer.php'; ?> <!-- Подключаем подвал проекта -->
Дизайн главной страницы если пользователь не авторизован:
Дизайн главной страницы если пользователь авторизован:
Теперь создадим последний файл в нашем проекте и назовём его «logout.php». Он необходим для удаления сессии пользователя, когда он авторизован. Листинг файла:
<?php 
require __DIR__ . '/header.php'; // подключаем шапку проекта
require "db.php"; // подключаем файл для соединения с БД

// Производим выход пользователя
unset($_SESSION['logged_user']);

// Редирект на главную страницу
header('Location: index.php');

require __DIR__ . '/footer.php'; // Подключаем подвал проекта
?>
После этого можно запустить страничку в браузере и проверить результат работы. Если Вы правильно записали, тогда все должно работать идеально, но если есть ошибки значит проверьте правильность кода.

Структура проекта в виде дерева:
На этом мы заканчиваем создание системы регистрации и авторизации на PHP. В комментариях жду Ваших предложений по доработке этого приложения. Удачи в разработке!
Самоучитель по PHP