Сценарий авторизации пользователя

Если вам необходимо реализовать регистрацию пользователей на вашем сайте, посмотрите мой пример -Предложу несколько своих вариантов решений тех или иных задач, касающихся PHP -Примеры
  • Таблица в базе данных
  • Внешний вид форм
  • Регистрация пользователя
  • Авторизация пользователя
  • Проверка авторизации пользователя
  • Завершение сеанса пользователя

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

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

Вероятно, вы хотели бы увидеть более современный способ создания такой формы. Полное его современное и актуальное представление у меня пока что еще в планах, но зато вы можете увидеть, что форму обратной связи можно построить с помощью объектно-ориентированных приемов в PHP.

Для начала давайте оговорим все шаги, которые сделаем далее. Что нам вообще нужно? Нам нужен сценарий, который будет регистрировать пользователя, авторизовать пользователя, переадресовывать пользователя куда-либо после авторизации. Также нам нужно будет создать страницу, которая будет защищена от доступа неавторизованных пользователей. Для регистрации и авторизации нам необходимо будет создать HTML-формы. Информацию о зарегистрированных пользователях мы будем хранить в базе данных. Это значит, что нам еще нужен скрипт подключения к СУБД. Всю работу у нас будут выполнять функции, которые мы сами напишем. Эти функции мы сохраним в отдельный файл.

Итак, нам нужны следующие файлы:

  • соединение с СУБД;
  • пользовательские функции;
  • авторизация;
  • регистрация;
  • защищенная страница;
  • сценарий завершения работы пользователя;
  • сценарий, проверяющий статус авторизации пользователя;
  • таблица стилей для простейшего оформления наших страниц.

Всё это будет бессмысленно, если у вас нет соответствующей таблицы в базе данных. Запустите инструмент управления своим СУБД (PhpMyAdmin или командную строку, как удобнее) и выполните в нем следующий запрос:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `login` char(16) NOT NULL,
  `password` char(40) NOT NULL,
  `reg_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Наши файлы со сценариями я назову так (все они будут лежать в одном каталоге):

  • database.php;
  • functions.php;
  • login.php;
  • registration.php;
  • index.php;
  • logout.php;
  • checkAuth.php;
  • style.css.

Назначение каждого из них, я уверен, вам понятно. Начнем со скрипта соединения с СУБД. Вы его уже видели. Просто сохраните код этого скрипта в файле с именемdatabase.php. Пользовательские функции мы будем объявлять в файлеfunctions.php. Как это всё будет работать? Неавторизованный пользователь пытается получить доступ к защищенному документуindex.php, система проверяет авторизован ли пользователь, если пользователь не авторизован, он переадресовывается на страницу авторизации. На странице авторизации пользователь должен видеть форму авторизации. Давайте сделаем её.

<html>
<head>
	<title>Авторизация пользователей</title>
	<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form action="" method="post">
	<div class="row">
		<label for="login">Ваш логин:</label>
		<input type="text" class="text" name="login" id="login" />
	</div>
	<div class="row">
		<label for="password">Ваш пароль:</label>
		<input type="password" class="text" name="password" id="password" />
	</div>
	<div class="row">
		<input type="submit" name="submit" id="btn-submit" value="Авторизоваться" />
	</div>
</form>
<p class="to_reg">Если вы не зарегистрированы в системе, <a href="registration.php">зарегистрируйтесь</a>.</p>
</body>
</html>

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

/* файл style.css */
.row {
	margin-bottom:10px;
	width:220px;
}
	.row label {
		display:block;
		font-weight:bold;
	}
	.row input.text {
		font-size:1.2em;
		padding:2px 5px;
	}
.to_reg {
	font-size:0.9em;
}
.instruction {
	font-size:0.8em;
	color:#aaaaaa;
	margin-left:2px;
	cursor:default;
}
.error {
	color:red;
	margin-left:3px;
}

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

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

<html>
<head>
	<title>Регистрация пользователей</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
	<form action="" method="post">
		<div class="row">
			<label for="login">Укажите ваш логин:</label>
			<input type="text" class="text" name="login" id="login" value="<?=$fields['login'];?>" />
			<div class="error" id="login-error"><?=$errors['login'];?></div>
			<div class="instruction" id="login-instruction">В имени пользователя могут быть только символы латинского алфавита, цифры, символы '_', '-', '.'. Длина имени пользователя должна быть не короче 4 символов и не длиннее 16 символов</div>
		</div>
		<div class="row">
			<label for="password">Напишите ваш пароль:</label>
			<input type="password" class="text" name="password" id="password" value="" />
			<div class="error" id="password-error"><?=$errors['password'];?></div>
			<div class="instruction" id="password-instruction">В пароле вы можете использовать только символы латинского алфавита, цифры, символы '_', '!', '(', ')'. Пароль должен быть не короче 6 символов и не длиннее 16 символов</div>
		</div>
		<div class="row">
			<label for="password_again">Повторите введенный пароль:</label>
			<input type="password" class="text" name="password_again" id="password_again" value="" />
			<div class="error" id="password_again-error"><?=$errors['password_again'];?></div>
			<div class="instruction" id="password_again-instruction">Повторите введенный ранее пароль</div>
		</div>
		<div class="row">
			<!-- Кнопка отправки данных формы -->
			<input type="submit" name="submit" id="btn-submit" value="Зарегистрироваться" />
			
			<!-- Кнопка сброса полей формы к исходному состоянию -->
			<input type="reset" name="reset" id="btn-reset" value="Очистить" />
		</div>
	</form>
</body>
</html>

Вы, наверное, обратили внимание на то, что в HTML-коде присутствуют переменные PHP. Они являются содержимым атрибутов текстовых полей форм, содержимом контейнеров, предназначенных для вывода ошибок. Но мы не инициализировали эти переменные. Давайте сделаем это.

<?
// Инициализируем переменные для введенных значений и возможных ошибок
$errors = array();
$fields = array();
?>
<html>
<head>
	<title>Регистрация пользователей</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
	<form action="" method="post">
		<div class="row">
			<label for="login">Укажите ваш логин:</label>
			<input type="text" class="text" name="login" id="login" value="<?=$fields['login'];?>" />
			<div class="error" id="login-error"><?=$errors['login'];?></div>
			<div class="instruction" id="login-instruction">В имени пользователя могут быть только символы латинского алфавита, цифры, символы '_', '-', '.'. Длина имени пользователя должна быть не короче 4 символов и не длиннее 16 символов</div>
		</div>
		<div class="row">
			<label for="password">Напишите ваш пароль:</label>
			<input type="password" class="text" name="password" id="password" value="" />
			<div class="error" id="password-error"><?=$errors['password'];?></div>
			<div class="instruction" id="password-instruction">В пароле вы можете использовать только символы латинского алфавита, цифры, символы '_', '!', '(', ')'. Пароль должен быть не короче 6 символов и не длиннее 16 символов</div>
		</div>
		<div class="row">
			<label for="password_again">Повторите введенный пароль:</label>
			<input type="password" class="text" name="password_again" id="password_again" value="" />
			<div class="error" id="password_again-error"><?=$errors['password_again'];?></div>
			<div class="instruction" id="password_again-instruction">Повторите введенный ранее пароль</div>
		</div>
		<div class="row">
			<!-- Кнопка отправки данных формы -->
			<input type="submit" name="submit" id="btn-submit" value="Зарегистрироваться" />
			
			<!-- Кнопка сброса полей формы к исходному состоянию -->
			<input type="reset" name="reset" id="btn-reset" value="Очистить" />
		</div>
	</form>
</body>
</html>

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

Нам нужно, чтобы поля логина и пароля не были пустыми. Затем необходимо проверить логин на соответствие требованиям. Пароль также должен соответствовать описанным требованиям, а повторно указанный пароль должен с ним совпадать и, кроме того, они должны быть идентичны. Если какое-то из этих условий не выполняется, обработка данных формы должна быть прекращена, в массив сообщений об ошибке должно быть записано соответствующее оповещение, и оно должно быть отображено пользвателю. Для удобства пользователя мы сохраним введенный им логин (если он его указал), записав его значение в массив$fields.

Если всё нормально, в окне вашего броузера, обратившись к документу registration.php, вы должны увидеть примерно такую форму:

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

/**
  * functions.php
  * Файл с пользовательскими функциями
  */
  
// Подключаем файл с параметрами подключения к СУБД
require_once('database.php');

// Проверка имени пользователя
function checkLogin($str) {
	// Инициализируем переменную с возможным сообщением об ошибке
	$error = '';
	
	// Если отсутствует строка с логином, возвращаем сообщение об ошибке
	if(!$str) {
		$error = 'Вы не ввели имя пользователя';
		return $error;
	}
	
	/**
	  * Проверяем имя пользователя с помощью регулярных выражений
	  * Логин должен быть не короче 4, не длиннее 16 символов
	  * В нем должны быть символы латинского алфавита, цифры, 
	  * в нем могут быть символы '_', '-', '.'
	  */
	$pattern = '/^[-_.a-zd]{4,16}$/i';	
	$result = preg_match($pattern, $str);
	
	// Если проверка не прошла, возвращаем сообщение об ошибке
	if(!$result) {
		$error = 'Недопустимые символы в имени пользователя или имя пользователя слишком короткое (длинное)';
		return $error;
	}
	
	// Если же всё нормально, вернем значение true
	return true;
}

// Проверка пароля пользователя
function checkPassword($str) {
	// Инициализируем переменную с возможным сообщением об ошибке
	$error = '';
	
	// Если отсутствует строка с логином, возвращаем сообщение об ошибке
	if(!$str) {
		$error = 'Вы не ввели пароль';
		return $error;
	}
	
	/**
	  * Проверяем пароль пользователя с помощью регулярных выражений
	  * Пароль должен быть не короче 6, не длиннее 16 символов
	  * В нем должны быть символы латинского алфавита, цифры, 
	  * в нем могут быть символы '_', '!', '(', ')'
	  */
	$pattern = '/^[_!)(.a-zd]{6,16}$/i';	
	$result = preg_match($pattern, $str);
	
	// Если проверка не прошла, возвращаем сообщение об ошибке
	if(!$result) {
		$error = 'Недопустимые символы в пароле пользователя или пароль слишком короткий (длинный)';
		return $error;
	}
	
	// Если же всё нормально, вернем значение true
	return true;
}

Теперь нам нужно изменить файл registration.php, чтобы задействовать объявленные нами функции. В сценарий мы добавим условие, проверяющее нажатие кнопки регистрации. Внутри этого условия запускается проверка логина и паролей. В случае, если какая-то из проверок завершается неудачей, мы вновь отображаем форму, и выводим сообщение об ошибке. Если ошибок нет, мы регистрируем пользователя, форму регистрации при этом уже не отображаем, сообщаем пользователю об успешной регистрации, и с помощью функцииheader() переадресовываем его к форме авторизации.

<?
/**
  * registration.php
  * Страница регистрации пользователей. Предполагается, что в вашей
  * базе данных присутствует таблица пользователей users, в которой
  * есть поля id, login, password, reg_date
  */
  
// Подключаем файл с пользовательскими функциями
require_once('functions.php');

// Инициализируем переменные для введенных значений и возможных ошибок
$errors = array();
$fields = array();

// Заранее инициализируем переменную регистрации, присваивая ей ложное значение
$reg = false;

// Если была нажата кнопка регистрации
if(isset($_POST['submit'])) {
	// Делаем массив сообщений об ошибках пустым
	$errors['login'] = $errors['password'] = $errors['password_again'] = '';
	
	// С помощью стандартной функции trim() удалим лишние пробелы
	// из введенных пользователем данных
	$fields['login'] = trim($_POST['login']);
	$password = trim($_POST['password']);
	$password_again = trim($_POST['password_again']);
	
	// Если логин не пройдет проверку, будет сообщение об ошибке
	$errors['login'] = checkLogin($fields['login']) === true ? '' : checkLogin($fields['login']);
	
	// Если пароль не пройдет проверку, будет сообщение об ошибке
	$errors['password'] = checkPassword($password) === true ? '' : checkPassword($password);
	
	// Если пароль введен верно, но пароли не идентичны, будет сообщение об ошибке
	$errors['password_again'] = (checkPassword($password) === true && $password === $password_again) ? '' : 'Введенные пароли не совпадают';
	
	// Если ошибок нет, нам нужно добавить информацию о пользователе в БД
	if($errors['login'] == '' && $errors['password'] == '' && $errors['password_again'] == '') {
		// Вызываем функцию регистрации, её результат записываем в переменную
		$reg = registration($fields['login'], $password);
		
		// Если регистрация прошла успешно, сообщаем об этом пользователю
		// И создаем заголовок страницы, который выполнит переадресацию к форме авторизации
		if($reg === true) {
			$message = '<p>Вы успешно зарегистрировались в системе. Сейчас вы будете переадресованы к странице авторизации. Если это не произошло, перейдите на неё по <a href="login.php">прямой ссылке</a>.</p>';
			header('Refresh: 5; URL = login.php');
		}
		// Иначе сообщаем пользователю об ошибке
		else {
			$errors['full_error'] = $reg;
		}
	}
}

?>
<html>
<head>
	<title>Регистрация пользователей</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
	<form action="" method="post">
		<div class="row">
			<label for="login">Укажите ваш логин:</label>
			<input type="text" class="text" name="login" id="login" value="<?=$fields['login'];?>" />
			<div class="error" id="login-error"><?=$errors['login'];?></div>
			<div class="instruction" id="login-instruction">В имени пользователя могут быть только символы латинского алфавита, цифры, символы '_', '-', '.'. Длина имени пользователя должна быть не короче 4 символов и не длиннее 16 символов</div>
		</div>
		<div class="row">
			<label for="password">Напишите ваш пароль:</label>
			<input type="password" class="text" name="password" id="password" value="" />
			<div class="error" id="password-error"><?=$errors['password'];?></div>
			<div class="instruction" id="password-instruction">В пароле вы можете использовать только символы латинского алфавита, цифры, символы '_', '!', '(', ')'. Пароль должен быть не короче 6 символов и не длиннее 16 символов</div>
		</div>
		<div class="row">
			<label for="password_again">Повторите введенный пароль:</label>
			<input type="password" class="text" name="password_again" id="password_again" value="" />
			<div class="error" id="password_again-error"><?=$errors['password_again'];?></div>
			<div class="instruction" id="password_again-instruction">Повторите введенный ранее пароль</div>
		</div>
		<div class="row">
			<!-- Кнопка отправки данных формы -->
			<input type="submit" name="submit" id="btn-submit" value="Зарегистрироваться" />
			
			<!-- Кнопка сброса полей формы к исходному состоянию -->
			<input type="reset" name="reset" id="btn-reset" value="Очистить" />
		</div>
	</form>
</body>
</html>

В скрипте вы должны были заметить еще одну новую функцию —registration(). А мы её еще не объявляли. Давайте сделаем это.

// Функция регистрации пользователя
function registration($login, $password) {
	// Инициализируем переменную с возможным сообщением об ошибке
	$error = '';
	
	// Если отсутствует строка с логином, возвращаем сообщение об ошибке
	if(!$login) {
		$error = 'Не указан логин';
		return $error;
	} 
	elseif(!$password) {
		$error = 'Не указан пароль';
		return $error;
	}
	
	// Проверяем не зарегистрирован ли уже пользователь
	// Подключаемся к СУБД
	connect();
	
	// Пишем строку запроса
	$sql = "SELECT `id` FROM `users` WHERE `login`='" . $login . "'";
	// Делаем запрос к базе
	$query = mysql_query($sql) or die("<p>Невозможно выполнить запрос: " . mysql_error() . ". Ошибка произошла в строке " . __LINE__ . "</p>");
	// Смотрим на количество пользователей с таким логином, если есть хоть один,
	// возвращаем сообщение об ошибке
	if(mysql_num_rows($query) > 0) {
		$error = 'Пользователь с указанным логином уже зарегистрирован';
		return $error;
	}
	
	// Если такого пользователя нет, регистрируем его
	// Пишем строку запроса
	$sql = "INSERT INTO `users` 
			(`id`,`login`,`password`) VALUES 
			(NULL, '" . $login . "','" . $password . "')";
	// Делаем запрос к базе
	$query = mysql_query($sql) or die("<p>Невозможно добавить пользователя: " . mysql_error() . ". Ошибка произошла в строке " . __LINE__ . "</p>");
	
	// Не забываем отключиться от СУБД
	mysql_close();
	
	// Возвращаем значение true, сообщающее об успешной регистрации пользователя
	return true;
}

Если всё нормально, ваш пользователь будет зарегистрирован. Можете потестировать форму. Попробуйте зарегистрировать пользователей с одинаковыми логинами. После успешной регистрации пользователь будет перееадресован к форме авторизации. Ранее мы просто создали разметку для отображения этой формы. Так как в её атрибутеaction не указан никакой параметр, данные, отправленные формой, будут обрабатываться в этом же сценарии. Значит нам нужно написать код для обработки, и добавить его в документ login.php.

<?
/**
  * Страница авторизации пользователей. Предполагается, 
  * что в вашей базе данных присутствует таблица users,
  * в которой существуют поля id, login и password
  */
// Подлючаем файл с пользовательскими функциями
require_once('functions.php');

// Заранее инициализируем переменную авторизации, присвоив ей ложное значение
$auth = false;

// Если была нажата кнопка авторизации
if(isset($_POST['submit'])) {
	// Делаем массив сообщений об ошибках пустым
	$errors['login'] = $errors['password'] = $errors['password_again'] = '';
	
	// С помощью стандартной функции trim() удалим лишние пробелы
	// из введенных пользователем данных
	$login = trim($_POST['login']);
	$password = trim($_POST['password']);
	
	// Авторизуем пользователя
	// Вызываем функцию регистрации, её результат записываем в переменную
	$auth = authorization($login, $password);
	
	// Если авторизация прошла успешно, сообщаем об этом пользователю
	// И создаем заголовок страницы, который выполнит переадресацию на защищенную
	// от общего доступа страницу
	if($auth === true) {
		$message = '<p>Вы успешно авторизовались в системе. Сейчас вы будете переадресованы на главную страницу сайта. Если это не произошло, перейдите на неё по <a href="/">прямой&nbsp;ссылке</a>.</p>';
		header('Refresh: 5; URL = /');
	}
	// Иначе сообщаем пользователю об ошибке
	else {
		$errors['full_error'] = $auth;
	}
}
?>
<html>
<head>
	<title>Авторизация пользователей</title>
	<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<?
// Если запущен процесс авторизации, но она не была успешной,
// или же авторизация еще не запущена, отображаем форму авторизации
if($auth !== true) {
?>
	<!-- Блок для вывода сообщений об ошибках -->
	<div id="full_error" class="error" style="display:
	<?
	echo $errors['full_error'] ? 'inline-block' : 'none';
	?>
	;">
	<?
	// Выводим сообщение об ошибке, если оно есть
	echo $errors['full_error'] ? $errors['full_error'] : '';
	?>
	</div>
	<form action="" method="post">
		<div class="row">
			<label for="login">Ваш логин:</label>
			<input type="text" class="text" name="login" id="login" />
		</div>
		<div class="row">
			<label for="password">Ваш пароль:</label>
			<input type="password" class="text" name="password" id="password" />
		</div>
		<div class="row">
			<input type="submit" name="submit" id="btn-submit" value="Авторизоваться" />
		</div>
	</form>
	<p class="to_reg">Если вы не зарегистрированы в системе, <a href="registration.php">зарегистрируйтесь</a>.</p>
<?
}	// Закрывающая фигурная скобка условного оператора проверки успешной авторизации
// Иначе выводим сообщение об успешной авторизации
else {
	print $message;
}

/**
  * Если всё правильно, будет выведено сообщение об успешной авторизации,
  * пользователь будет переадресован на защищенную страницу
  */
?>
</body>
</html>

Вы, наверное, заметили, что в скрипте авторизации у нас появилась ещё одна незнакомая функция —authorization(). Эта функция должна авторизовать пользователя, предварительно проверив, существует ли в базе данных зарегистрированный пользователь с таким логином и паролем. Если такой пользователь не будет найден, авторизация будет прервана, на экран будет выведено сообщение о неудаче. При успешной проверки функцияauthorization() запустит сессию, и запишет в неё значения логина и пароля пользователя, сообщит сценарию об успешности авторизации, и сценарий перенаправит пользователя на защищенную страницу ресурса.

/**
  * Функция авторизации пользователя.
  * Авторизация пользователей у нас будет осуществляться
  * с помощью сессий PHP.
  */
function authorization($login, $password) {
	// Инициализируем переменную с возможным сообщением об ошибке
	$error = '';
	
	// Если отсутствует строка с логином, возвращаем сообщение об ошибке
	if(!$login) {
		$error = 'Не указан логин';
		return $error;
	} 
	elseif(!$password) {
		$error = 'Не указан пароль';
		return $error;
	}
	
	// Проверяем не зарегистрирован ли уже пользователь
	// Подключаемся к СУБД
	connect();
	
	// Нам нужно проверить, есть ли такой пользователь среди зарегистрированных
	// Составляем строку запроса
	$sql = "SELECT `id` FROM `users` WHERE `login`='".$login."' AND `password`='".$password."'";
	// Выполняем запрос
	$query = mysql_query($sql) or die("<p>Невозможно выполнить запрос: " . mysql_error() . ". Ошибка произошла в строке " . __LINE__ . "</p>");
	
	// Если пользователя с такими данными нет, возвращаем сообщение об ошибке
	if(mysql_num_rows($query) == 0)	{
		$error = 'Пользователь с указанными данными не зарегистрирован';
		return $error;
	}
	
	// Если пользователь существует, запускаем сессию
	session_start();
	// И записываем в неё логин и пароль пользователя
	// Для этого мы используем суперглобальный массив $_SESSION
	$_SESSION['login'] = $login;
	$_SESSION['password'] = $password;
	
	// Не забываем закрывать соединение с базой данных
	mysql_close();

	// Возвращаем true для сообщения об успешной авторизации пользователя
	return true;
}

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

function checkAuth($login, $password) {
	// Если нет логина или пароля, возвращаем false
	if(!$login || !$password)	return false;
	
	// Проверяем зарегистрирован ли такой пользователь
	// Подключаемся к СУБД
	connect();
	
	// Составляем строку запроса
	$sql = "SELECT `id` FROM `users` WHERE `login`='".$login."' AND `password`='".$password."'";
	// Выполняем запрос
	$query = mysql_query($sql) or die("<p>Невозможно выполнить запрос: " . mysql_error() . ". Ошибка произошла в строке " . __LINE__ . "</p>");
	
	// Если пользователя с такими данными нет, возвращаем false;
	if(mysql_num_rows($query) == 0)	{
		return false;
	}

	// Не забываем закрывать соединение с базой данных
	mysql_close();	

	// Иначе возвращаем true
	return true;
}

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

/**
  * Скрипт проверки авторизации пользователей
  */

// Запускаем сессию, из которой будем извлекать логин и пароль
// авторизовавшихся пользователей
session_start();
  
// Подлючаем файл с пользовательскими функциями
require_once('functions.php');

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

// Если в сессии присуствуют данные и о логине, и о пароле,
// проверяем их
if(isset($_SESSION['login']) && $_SESSION['login'] && isset($_SESSION['password']) && $_SESSION['password']) {
	// Если проверка существующих данных завершается неудачей
	if(!checkAuth($_SESSION['login'], $_SESSION['password'])) {
		// Переадресовываем пользователя на страницу авторизации
		header('location: login.php');
		// Прекращаем выполнение скрипта
		exit;
	}
}
// Если данных либо о логине, либо о пароле пользователя нет,
// считаем что авторизации нет, переадресовываем пользователя
// на страницу авторизации
else {
	header('location: login.php');
	// Прекращаем выполнение сценария
	exit;
}

А теперь давайте создадим код нашей защищенной страницы. Он будет довольно-таки прост.

<?
/**
  * Защищенная страница. К ней возможен доступ только авторизованным
  * пользователям. Если пользователь не авторизован, ему предлагается 
  * авторизоваться, и доступ к сайту ограничивается. 
  */
require_once('checkAuth.php');
?>
<html>
<head>
	<title>Авторизация и регистрация пользователей</title>
</head>
<body>
<h1>Успешная авторизация.</h1>
<p>Вы получили доступ к защищенной странице. Вы можете <a href="logout.php">выйти</a> из системы.</p>
</body>
</html>

Как видите, в защищенном документе мы подключаем только один файл — checkAuth.php. Все остальные файлы подключаются уже в других сценариях. Поэтому наш код не выглядит громоздким. Регистрацию и авторизацию пользователей мы организовали. Теперь необходимо позволить пользователям выходить из системы. Для этого мы создадим сценарий в файле logout.php.

/**
  * Скрипт выхода пользователя из системы. Так как пользователи
  * авторизуются через сессии, их логин и пароль хранятся
  * в суперглобаном массиве $_SESSION. Чтобы осуществить
  * выход из системы, достаточно просто уничтожить значения
  * массива $_SESSION['login'] и $_SESSION['password'], после
  * чего мы переадресовываем пользователя к странице авторизации
  */

// Обязательно запускаем сессию
session_start();

unset($_SESSION['login']);
unset($_SESSION['password']);
header('location: login.php');

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

P.S. Я в курсе, что лучше писать объектно-ориентированный код, знаю, что передавать и хранить пароль в открытом виде не стоит, что информацию, заносимую в базу данных, необходимо предварительно проверять. Знаю. Об этом я здесь не буду говорить.

Доброго времени суток друзья! Давай с Вами рассмотрим регистрацию пользователей на PHP. Для начала давайте определим условия для нашей регистрации пользователей:

Условия для регистрации пользователей

  • Пароль шифруем при помощи алгоритма MD5
  • Пароль будем «солить»
  • Проверка на занятость Логина
  • Активация пользователя письмом.
  • Запись и хранение данных в СУБД MySQL

Для написание данного скрипта нам нужно понять, что такое регистрация пользователя. Регистрация пользователя – это получения данных реального пользователя, обработка и хранение данных.

Если объяснять простыми словами то регистрация это всего лишь запись и хранение определенных данных по которым мы можем авторизировать пользователя в нашем случае – это Логин и Пароль.

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

Регистрация и Авторизация на PHP + MySQL Структура каталогов

Рассмотрим структуру каталогов скриптов для реализации нашей регистрации с авторизацией. Нам нужно разбить скрипты на логические составляющие. Модули регистрации и авторизации мы поместив в отдельный каталог. Так же в отдельные каталоги мы поместим подключение к базе данных MySQL, файл с пользовательскими функциями, файл стилей CSS и наш шаблон HTML. Данная структура позволяет быстро ориентироваться в скриптах. Представьте себе, что у Вас большой сайт с кучей модулями и т.д. и если не будет порядка, то будет очень сложно что-то отыскать в таком бардаке.

Так как мы будем хранить все данные в СУБД MySQL, то давайте создадим не большую таблицу в которой будем хранить данные о регистрации.

Для начала нужно создать таблицу в базе данных. Таблицу назовем bez_reg где bez – это префикс таблицы, а reg название таблицы.

Структура таблицы: bez_reg


--
-- Структура таблицы `bez_reg`
--

CREATE TABLE IF NOT EXISTS `bez_reg` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `login` varchar(200) NOT NULL,
  `pass` varchar(32) NOT NULL,
  `salt` varchar(32) NOT NULL,
  `active_hex` varchar(32) NOT NULL,
  `status` int(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

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

Файл INDEX.PHP


<?php
/**
* Главный файл (переключатель)
* Site: https://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;

}

//Получаем данные с буфера
$content = ob_get_contents();
ob_end_clean();

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

Файл CONFIG.PHP


    <?php
     /**
     * Конфигурационный файл
     * Site: https://bezramok-tlt.ru
     * Регистрация пользователя письмом
     */


     //Ключ защиты
     if(!defined('BEZ_KEY'))
     {
         header("HTTP/1.1 404 Not Found");
         exit(file_get_contents('./404.html'));
     }

     //Адрес базы данных
     define('BEZ_DBSERVER','localhost');

     //Логин БД
     define('BEZ_DBUSER','');

     //Пароль БД
     define('BEZ_DBPASSWORD','');

     //БД
     define('BEZ_DATABASE','');

     //Префикс БД
     define('BEZ_DBPREFIX','bez_');

     //Errors
     define('BEZ_ERROR_CONNECT','Немогу соеденится с БД');

     //Errors
     define('BEZ_NO_DB_SELECT','Данная БД отсутствует на сервере');

     //Адрес хоста сайта
     define('BEZ_HOST','http://'. $_SERVER['HTTP_HOST'] .'/');

     //Адрес почты от кого отправляем
     define('BEZ_MAIL_AUTOR','Регистрация на http://bezramok-tlt.ru <no-reply@bezramok-tlt.ru>');
     ?>

Файл 404.HTML


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf8" />
        <title>Ошибка 404</title>
        </head>
        <body>
            <table width="700" cellpadding="4" cellspacing="1" border="0" align="center">
              <tr>
                <td>
                  <h1>Ошибка 404</h1>
                </td>
              </tr>
              <tr>
                <td>
                  <h2>
                    На странице произошла ошибка 404
                  </h2>
                </td>
              </tr>
              <tr>
                <td>
                  <span class="leftMenu"><a href="javascript:history.back(-1)">Вернуться</a></span>
                </td>
              </tr>
            </table>
        </body>
    </html>

Файл BD.PHP


    <?php
     /**
     * Подключение к базе данных
     * Site: https://bezramok-tlt.ru
     * Регистрация пользователя письмом
     */

     //Ключ защиты
     if(!defined('BEZ_KEY'))
     {
         header("HTTP/1.1 404 Not Found");
         exit(file_get_contents('./../404.html'));
     }

     //Соединение с БД MySQL
     $db_connect = mysql_connect( BEZ_DBSERVER, BEZ_DBUSER, BEZ_DBPASSWORD ) or die(BEZ_ERROR_CONNECT);

     define('BEZ_CONNECT', $db_connect);

     mysql_select_db( BEZ_DATABASE, BEZ_CONNECT )or die(BEZ_NO_DB_SELECT);

     //Устанавливаем кодировку UTF8
     mysql_query ("SET NAMES utf8");
     mysql_query ("set character_set_client='utf8'");
     mysql_query ("set character_set_results='utf8'");
     mysql_query ("set collation_connection='utf8_general_ci'");
     ?>

Файл INDEX.HTML


    <!DOCTYPE html>
    <html>
        <head>
            <!-- Start META -->
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <meta name="keywords" content="Регистрация пользователей PHP MySQL, Авторизация пользователей PHP MySQL" />
            <meta name="description" content="Регистрация пользователей PHP MySQL с активацией письмом" />
            <!-- TITLE -->
            <title>Регистрация пользователей PHP MySQL с активацией письмом</title>

            <!-- Start Sheets CSS -->
            <link href="./css/style.css" rel="stylesheet" type="text/css">
        </head>
        <body>
            <div id="wrap">
                <div id="menu">
                    <div class="menu">
                        <ul>
                            <li><a href="<?php echo BEZ_HOST; ?>less/reg/?mode=auth">Войти</a></li>
                            <li><a href="<?php echo BEZ_HOST; ?>less/reg/?mode=reg">Регистрация</a></li>
                        </ul>
                    </div>
                </div>
                <div style="clear:both;"></div>
                <div id="content">
                    <?php echo $content; ?>
                </div>
            </div>
        </body>
    </html>

Файл FUNCT.PHP


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

     //Ключ защиты
     if(!defined('BEZ_KEY'))
     {
         header("HTTP/1.1 404 Not Found");
         exit(file_get_contents('./../404.html'));
     }

     /**Функция экранирования вносимых данных
     *@param array $data
     */
     function escape_str($data)
     {
        if(is_array($data))
        {
            if(get_magic_quotes_gpc())
               $strip_data = array_map("stripslashes", $data);
               $result = array_map("mysql_real_escape_string", $strip_data);
               return  $result;
        }
        else
        {
            if(get_magic_quotes_gpc())
               $data = stripslashes($data);
               $result = mysql_real_escape_string($data);
               return $result;
        }
     }

     /**Отпровляем сообщение на почту
     * @param string  $to
     * @param string  $from
     * @param string  $title
     * @param string  $message
     */
     function sendMessageMail($to, $from, $title, $message)
     {
       //Адресат с отправителем
       //$to = $to;
       //$from = $from;

       //Формируем заголовок письма
       $subject = $title;
       $subject = '=?utf-8?b?'. base64_encode($subject) .'?=';

       //Формируем заголовки для почтового сервера
       $headers = "Content-type: text/html; charset="utf-8"rn";
       $headers .= "From: ". $from ."rn";
       $headers .= "MIME-Version: 1.0rn";
       $headers .= "Date: ". date('D, d M Y h:i:s O') ."rn";

       //Отправляем данные на ящик админа сайта
       if(!mail($to, $subject, $message, $headers))
          return 'Ошибка отправки письма!';
       else
          return true;
     }

      /**функция вывода ошибок
      * @param array  $data
      */
     function showErrorMessage($data)
     {
        $err = '<ul>'."n";

        if(is_array($data))
        {
            foreach($data as $val)
                $err .= '<li style="color:red;">'. $val .'</li>'."n";
        }
        else
            $err .= '<li style="color:red;">'. $data .'</li>'."n";

        $err .= '</ul>'."n";

        return $err;
     }

      /**Простая обертка для запросов к MySQL
      * @param string  $sql
      */
     function mysqlQuery($sql)
     {
        $res = mysql_query($sql);
        /* Проверяем результат
        Это показывает реальный запрос, посланный к MySQL, а также ошибку. Удобно при отладке.*/
        if(!$res)
        {
            $message  = 'Неверный запрос: ' . mysql_error() . "n";
            $message .= 'Запрос целиком: ' . $sql;
            die($message);
        }

        return $res;
     }

     /**Простой генератор соли
     * @param string  $sql
     */
     function salt()
     {
        $salt = substr(md5(uniqid()), -8);
        return $salt;
     }

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

Файл REG.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['status']) and $_GET['status'] == 'ok')
        echo '<b>Вы успешно зарегистрировались! Пожалуйста активируйте свой аккаунт!</b>';

     //Выводим сообщение об удачной регистрации
     if(isset($_GET['active']) and $_GET['active'] == 'ok')
        echo '<b>Ваш аккаунт на http://bezramok-tlt.ru успешно активирован!</b>';

     //Производим активацию аккаунта
     if(isset($_GET['key']))
     {
        //Проверяем ключ
        $sql = 'SELECT *
                FROM `'. BEZ_DBPREFIX .'reg`
                WHERE `active_hex` = "'. escape_str($_GET['key']) .'"';
        $res = mysqlQuery($sql);

        if(mysql_num_rows($res) == 0)
            $err[] = 'Ключ активации не верен!';

        //Проверяем наличие ошибок и выводим пользователю
        if(count($err) > 0)
            echo showErrorMessage($err);
        else
        {
            //Получаем адрес пользователя
            $row = mysql_fetch_assoc($res);
            $email = $row['login'];

            //Активируем аккаунт пользователя
            $sql = 'UPDATE `'. BEZ_DBPREFIX .'reg`
                    SET `status` = 1
                    WHERE `login` = "'. $email .'"';
            $res = mysqlQuery($sql);

            //Отправляем письмо для активации
            $title = 'Ваш аккаунт на http://bezramok-tlt.ru успешно активирован';
            $message = 'Поздравляю Вас, Ваш аккаунт на http://bezramok-tlt.ru успешно активирован';

            sendMessageMail($email, BEZ_MAIL_AUTOR, $title, $message);

            /*Перенаправляем пользователя на
            нужную нам страницу*/
            header('Location:'. BEZ_HOST .'less/reg/?mode=reg&active=ok');
            exit;
        }
     }
     /*Если нажата кнопка на регистрацию,
     начинаем проверку*/
     if(isset($_POST['submit']))
     {
        //Утюжим пришедшие данные
        if(empty($_POST['email']))
            $err[] = 'Поле Email не может быть пустым!';
        else
        {
            if(!preg_match("/^[a-z0-9_.-]+@([a-z0-9]+.)+[a-z]{2,6}$/i", $_POST['email']))
               $err[] = 'Не правильно введен E-mail'."n";
        }

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

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

        //Проверяем наличие ошибок и выводим пользователю
        if(count($err) > 0)
            echo showErrorMessage($err);
        else
        {
            /*Продолжаем проверять введеные данные
            Проверяем на совподение пароли*/
            if($_POST['pass'] != $_POST['pass2'])
                $err[] = 'Пароли не совподают';

            //Проверяем наличие ошибок и выводим пользователю
            if(count($err) > 0)
                echo showErrorMessage($err);
            else
            {
                /*Проверяем существует ли у нас
                такой пользователь в БД*/
                $sql = 'SELECT `login`
                        FROM `'. BEZ_DBPREFIX .'reg`
                        WHERE `login` = "'. escape_str($_POST['email']) .'"';
                $res = mysqlQuery($sql);

                if(mysql_num_rows($res) > 0)
                    $err[] = 'К сожалению Логин: <b>'. $_POST['email'] .'</b> занят!';

                //Проверяем наличие ошибок и выводим пользователю
                if(count($err) > 0)
                    echo showErrorMessage($err);
                else
                {
                    //Получаем ХЕШ соли
                    $salt = salt();

                    //Солим пароль
                    $pass = md5(md5($_POST['pass']).$salt);

                    /*Если все хорошо, пишем данные в базу*/
                    $sql = 'INSERT INTO `'. BEZ_DBPREFIX .'reg`
                            VALUES(
                                    "",
                                    "'. escape_str($_POST['email']) .'",
                                    "'. $pass .'",
                                    "'. $salt .'",
                                    "'. md5($salt) .'",
                                    0
                                    )';
                    $res = mysqlQuery($sql);

                    //Отправляем письмо для активации
                    $url = BEZ_HOST .'less/reg/?mode=reg&key='. md5($salt);
                    $title = 'Регистрация на http://bezramok-tlt.ru';
                    $message = 'Для активации Вашего акаунта пройдите по ссылке
                    <a href="'. $url .'">'. $url .'</a>';

                    sendMessageMail($_POST['email'], BEZ_MAIL_AUTOR, $title, $message);

                    //Сбрасываем параметры
                    header('Location:'. BEZ_HOST .'less/reg/?mode=reg&status=ok');
                    exit;
                }
            }
        }
     }

    ?>

Файл REG_FORM.HTML


    <h2>Регистрация пользователей PHP MySQL с активацией письмом</h2>
    <form action="" method="POST">
        <table>
            <tr>
                <td>E-mail<font color="red">*</font>:</td>
                <td><input type="text" size="30" name="email"></td>
            </tr>
            <tr>
                <td>Пароль<font color="red">*</font>:</td>
                <td><input type="password" size="30" maxlength="20" name="pass"></td>
            </tr>
            <tr>
                <td>Подтверждения пароля<font color="red">*</font>:</td>
                <td><input type="password" size="30" maxlength="20" name="pass2"></td>
            </tr>
            <tr>
                <td>&nbsp;</td>
                <td colspan="2"><input type="submit" value="Зарегистроваться" name="submit"></td>
            </tr>
        </table>
    </form>
<br>Поля со значком <font color="red">*</font> обязательны для заполнения

Так как регистрация пользователей у нас готова, самое время написать авторизацию. Создадим форму для авторизации
пользователей, далее напишем обработчик формы авторизации и на последок сделаем скрипт show.php который
будет показывать нам авторизированны мы в системе или нет.

Файл AUTH.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($_POST['submit']))
     {
        if(empty($_POST['email']))
            $err[] = 'Не введен Логин';

        if(empty($_POST['pass']))
            $err[] = 'Не введен Пароль';

        //Проверяем наличие ошибок и выводим пользователю
        if(count($err) > 0)
            echo showErrorMessage($err);
        else
        {
            /*Создаем запрос на выборку из базы
            данных для проверки подлиности пользователя*/
            $sql = 'SELECT *
                    FROM `'. BEZ_DBPREFIX .'reg`
                    WHERE `login` = "'. escape_str($_POST['email']) .'"
                    AND `status` = 1';
            $res = mysqlQuery($sql);

            //Если логин совподает, проверяем пароль
            if(mysql_num_rows($res) > 0)
            {
                //Получаем данные из таблицы
                $row = mysql_fetch_assoc($res);

                if(md5(md5($_POST['pass']).$row['salt']) == $row['pass'])
                {
                    $_SESSION['user'] = true;

                    //Сбрасываем параметры
                    header('Location:'. BEZ_HOST .'less/reg/?mode=auth');
                    exit;
                }
                else
                    echo showErrorMessage('Неверный пароль!');
            }
            else
                echo showErrorMessage('Логин <b>'. $_POST['email'] .'</b> не найден!');
        }

     }

    ?>

Файл AUTH_FORM.HTML


    <h2>Введите свой Логин и Пароль для входа!</h2>
    <form action="" method="POST">
        <table>
            <tr>
                <td>E-mail:</td>
                <td><input type="text" size="30" name="email"></td>
            </tr>
            <tr>
                <td>Пароль:</td>
                <td><input type="password" size="30" maxlength="20" name="pass"></td>
            </tr>
            <tr>
                <td>&nbsp;</td>
                <td colspan="2"><input type="submit" value="Войти" name="submit"></td>
            </tr>
        </table>
    </form>

Файл SHOW.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($user === false)
        echo '<h3>Доступ закрыт, Вы не вошли в систему!</h3>'."n";

     if($user === true)
        echo '<h3>Поздравляю, Вы вошли в систему!</h3>'."n";
     ?>

Автор не несет ответственности за использования данных скриптов у себя на сайте. Вы можете их использовать на свой страх и риск!

Для тех у кого последняя версия PHP выкладываю данный скрипт с использованием PDO т.к. расширение MySQL устарело и было удалено из новой версии PHP. Скачать регистрация и авторизация php mysql pdo

Архив обновлен 24.02.2015г.

Внимание: Если вы используете данный скрипт на локальном сервере типа DENWER, XAMPP, то не
стоит ждать писем на свой почтовый ящик. Письма лежат в заглушке sendmail. В Denwer вы их можете
найти по пути Z:tmp!sendmail открыть данные файлы вы сможете в любом почтовом клиенте.

Скачать: Регистрация и Авторизация на PHP + MySQL

система авторизации

От автора: рано или поздно каждый веб-разработчик сталкивается с задачей по ограничению доступа к некоей странице/страницам или каталогу. Это может быть просто секретная страница на сайте, административная часть сайта или любой другой раздел, доступ к которому мы хотим ограничить и предоставлять только по паролю. Для этого можно, конечно же, воспользоваться средствами сервера. Думаю, на любом современном хостинге есть функция паролирования директории, где можно создать пользователя, назначить ему пароль и, после паролирования директории, доступ к закрытому каталогу будет предоставлен только после правильного ввода логина и пароля. Но иногда хочется написать что-то самому, что-то быстрое, простое, но вместе с тем — надежное…

В этом уроке мы попробуем написать свою простую систему авторизации. У нас будет секретная страница — допустим, это будет страница администратора, доступ к которой мы будем предоставлять только для авторизованного пользователя. Наша система авторизации будет основана на работе механизма сессий. Перед продолжением этого урока я рекомендую Вам ознакомиться с одним из предыдущих своих уроков, в котором мы, в частности, рассматриваем работу сессий — //webformyself.com/kak-opredelit-ip-adres-polzovatelya/.

Время ролика: 31:32

Ссылка для скачивания исходников: Скачать исходники

Ссылка для скачивания всего архива (видео+исходники): Скачать одним архивом. Размер: 47.7 mb.

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать веб-приложение на PHP с полного нуля

Получить курс сейчас!

Вкратце всю работу с сессиями можно разделить на 3 этапа:

Открытие сессии. На всех страницах, где подразумевается работа с сессиями, обязательно должен быть осуществлен старт сессии функцией session_start().

Регистрация сессионных переменных.

Разрегистрирование сессионных переменных при помощи функции unset() и закрытие сессии функцией session_destroy().

Шаг 1

Итак, для нашей работы создадим 3 файла — Главная страница (index.php), Контакты (contact.php) и Админка (admin.php). Обращаю внимание на то, что расширение файла, к которому мы будем ограничивать доступ должно быть .php. Как Вы догадались, ограничивать доступ мы будем к файлу admin.php. Код всех файлов самый простой — это своеобразное меню в строку со ссылками на другие страницы, и под ним индивидуальный текст каждой страницы, чтобы мы могли отличать их друг от друга. Вот, к примеру, код индексной страницы:

<p><a href=«index.php»>Главная</a> | <a href=«contact.php»>Контакты</a> | <a href=«admin.php»>Админка</a></p>

<hr />

Это главная страница

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

Шаг 2

Пока что мы свободно можем ходить по всем страницам, включая страницу админки. Как же мы ограничим к ней доступ? Каков вообще будет алгоритм? Мы будем делать следующее: в самом начале страницы мы будем проверять, есть ли нужная нам метка в сессии или, проще говоря, существует ли определенная сессионная переменная (также можно проверять равно ли значение сессионной переменной определенному значению). Если такой переменной нет, значит пользователь, запрашивающий эту страницу, не авторизован, а значит мы осуществим его редирект на страницу авторизации, где ему будет предложено заполнить форму с именем и паролем. Алгоритм предельно прост — реализуем его. Переходим к файлу admin.php, открываем в самом верху конструкцию PHP и напишем такой код:

<?php

session_start();

if(!$_SESSION[‘admin’]){

header(«Location: enter.php»);

exit;

}

?>

Давайте теперь прочитаем это код. Во-первых, мы открыли сессию, как Вы помните — это обязательное условие при работе с сессиями. Далее, мы создали простое условие, которое можно прочитать так: «если в массиве $_SESSION не существует элемента admin — будем выполнять блок действий, заключенный в операторные скобки». А в блоке кода мы при помощи функции header() производим редирект пользователя на страницу enter.php (это страница авторизации). После функции header() обязательно завершаем выполнение скрипта при помощи функции exit(). Если же условие не выполнится, т.е., в массиве $_SESSION будет элемент admin — это значит, что пользователь уже успешно авторизован, и мы пропустим блок действия в операторных скобках, т.е., никакого редиректа происходить не будет, и мы покажем запрошенную страницу.

Шаг 3

Теперь нам нужно создать страницу авторизации — enter.php. Для этого скопируем код, к примеру, страницы contact.php, создадим новый файл и вставим в него скопированный код. Файл сохраняем под именем enter.php. Теперь на этой странице напишем простенькую форму для ввода логина и пароля:

<p><a href=«index.php»>Главная</a> | <a href=«contact.php»>Контакты</a> | <a href=«admin.php»>Админка</a></p>

<hr />

Это страница авторизации.

<br />

<form method=«post»>

Username: <input type=«text» name=«user» /><br />

Password: <input type=«password» name=«pass» /><br />

<input type=«submit» name=«submit» value=«Войти» />

</form>

Здесь все просто. В форме 2 поля: поле для ввода логина (ему мы дали имя «user») и поле для пароля (с именем «pass»). Также мы создали кнопку (имя «submit»), по нажатию на которую будут отосланы данные из формы. Данные отсылаются методом post — это мы указали в атрибуте method тега form — и будут обработаны на этой же странице. Теперь мы можем попробовать зайти на страницу админки. Если все сделано без ошибок — мы туда попасть не сможем, а неизменно будем оказываться на странице авторизации.

Замечательно!

Шаг 4

Далее нам нужно написать на странице с формой ее обработчик, который будет принимать данные из формы и сравнивать, совпадают ли логин и пароль из формы с теми, которые есть у нас. Для этого откроем вверху страницы авторизации конструкцию PHP и начнем писать код. Для начала мы должны открыть сессию — ведь именно здесь мы будем создавать метку в сессии, если получены верные логин и пароль. На этой же странице мы будем хранить логин и пароль администратора. Обычно эти данные хранятся в базе данных (БД), но у нас будет только 1 пользователь (администратор), а потому хранить его данные для входа в БД не совсем рационально. Если же пользователей будет не один, т.е., мы, к примеру, пишем проект, в котором имеется регистрация, то, конечно же, без БД в таком случае обойтись будет сложно.

Итак, наш логин будет «admin» и хранить мы его будем в переменной $admin. Пароль будет «mypass» и он будет храниться в переменной $pass. Но хранить пароли в открытом виде не принято — это противоречит принципам безопасности. Хранить пароль мы будем в зашифрованном виде, а зашифровать его нам поможет функция md5(). Эта функция шифрует строку по специальному алгоритму, и на выходе мы получаем строку из 32 символов (ее называют хеш). Если мы зашифруем строку «mypass» (это можно сделать, например, в файле contact.php):

<?php

echo md5(‘mypass’);

?>

то на выходе получим строку «a029d0df84eb5549c641e04a9ef389e5» — это и будет наш зашифрованный пароль. Пока что код страницы авторизации будет таким:

<?php

session_start();

$admin = ‘admin’;

$pass = ‘a029d0df84eb5549c641e04a9ef389e5’;

?>

<p><a href=«index.php»>Главная</a> | <a href=«contact.php»>Контакты</a> | <a href=«admin.php»>Админка</a></p>

<hr />

Это страница авторизации.

<br />

<form method=«post»>

Username: <input type=«text» name=«user» /><br />

Password: <input type=«password» name=«pass» /><br />

<input type=«submit» name=«submit» value=«Войти» />

</form>

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать веб-приложение на PHP с полного нуля

Получить курс сейчас!

Шаг 5

Теперь проверим то, что мы получили из формы с тем, что у нас есть в переменных с логином и паролем. Делать это мы будем по условию — только в том случае, если нажата кнопка формы. Как мы можем это проверить? У кнопки есть имя («submit»), а данные мы передаем методом post. Соответственно, мы можем просто проверить, существует ли элемент submit в массиве $_POST. Если есть — кнопка была нажата, и мы будем выполнять действия по проверке присланных данных, иначе — ничего делать не будем. После объявления логина и пароля пишем условие:

if($_POST[‘submit’]){

if($admin == $_POST[‘user’] AND $pass == md5($_POST[‘pass’])){

$_SESSION[‘admin’] = $admin;

header(«Location: admin.php»);

exit;

}else echo ‘<p>Логин или пароль неверны!</p>’;

}

Условие по проверке логина и пароля мы сделали как бы двойным. Сделано это при помощи логического оператора AND (его также можно записать таким образом — «&&»). Условие можно прочитать так: «если(переменная $admin равна элементу user в массиве $_POST И переменная $pass равна хешу элемента pass в массиве $_POST) то {выполняем блок действий}else выводим на экран текст ‘Логин или пароль неверны!’

Если же пара логин-пароль совпадает, то мы регистрируем сессионную переменную $_SESSION[‘admin’] и перенаправляем пользователя на страницу админки — admin.php.
Попробуем теперь протестировать то, что мы уже создали. Если мы введем заведомо ложные логин и пароль, то получим предупреждающее сообщение, что «Логин или пароль неверны!». Попробуем теперь ввести правильные данные для входа. Если мы нигде не ошиблись, то после нажатия на кнопку «Войти» мы окажемся на странице админки.

Отлично!

Шаг 6

Теперь осталось дописать некоторые мелочи. К примеру, мы сейчас авторизованы в системе, но если мы введем в адресной строке адрес страницы авторизации, то спокойно попадем на нее и увидим форму авторизации. Такого быть не должно — форму должен видеть только неавторизованный пользователь. Как мы можем исправить это? Помним, что на странице admin.php мы проверяли, есть ли метка в сессии. Если ее нет — мы переводили пользователя на страницу авторизации. Здесь мы можем сделать то же самое, только наоборот. Т.е., мы также проверяем, есть ли метка в сессии. Только теперь мы будем переводить пользователя на страницу админки, если такая метка есть. Это, в принципе, логично. Если есть метка, значит пользователь уже авторизован, и мы его можем перевести на страницу админки. На странице enter.php после старта сессии допишем такой код:

if($_SESSION[‘admin’]){

header(«Location: admin.php»);

exit;

}

Теперь если авторизованный пользователь попробует ввести в адресную строку имя страницы авторизации — он будет переведен на страницу админки. Не авторизованный пользователь же сможет свободно попасть на страницу авторизации.

Шаг 7

Следующий момент, который нам нужно предусмотреть — это реализация выхода авторизованного пользователя, т.е., допустим, администратор закончил свою работу и ему нужно выйти, чтобы никто посторонний не смог работать под его учетной записью. Для этого добавим на странице admin.php ссылку «Выход». Ссылка будет вести на эту же страницу, только к ней будет добавлен нужный нам параметр. Параметр добавляется при помощи вопросительного знака:

<a href=«admin.php?do=logout»>Выход</a>

Эту ссылку можно поставить в том месте, в котором нам нужно — я поставлю ее после текста страницы. Относительно параметра — он будет передан методом GET (вспоминаем, что из формы мы передавали данные вторым параметром — POST). При использовании этого метода данные присоединяются к адресу в адресной строке и отделены от адреса как раз вопросительным знаком. Мы передаем один параметр — do — и при этом присвоили ему значение «logout». Как теперь мы можем разавторизовать пользователя? Очень просто — здесь нам помогут второй и третий этапы при работе с сессиями. При загрузке страницы мы можем проверить значение элемента do из массива $_GET. Если оно будет равно строке «logout» — мы просто разрегистрируем сессионную переменную $_SESSION[‘admin’] и разрушим сессию. Соответственно, метки в сессии после этого не будет и в следующем блоке, где мы проверяем наличие метки, пользователь будет перенаправлен на страницу авторизации. Все просто.

Итак, на странице admin.php допишем условие после старта сессии (до проверки наличия метки):

if($_GET[‘do’] == ‘logout’){

unset($_SESSION[‘admin’]);

session_destroy();

}

Теперь можно попробовать перейти по ссылке «Выход». После выхода мы окажемся на странице авторизации и увидим форму для авторизации. Попасть теперь на страницу админки мы не сможем, пока не авторизуемся.

Шаг 8

И последний штрих. Мы можем ограничивать доступ не только к странице админки, но и к любой другой. Для этого достаточно открыть сессию и проверить наличие метки в ней. Чтобы не копировать на каждую новую страницу эти блоки кода — мы их можем вынести в отдельный файл (auth.php) и затем просто подключать этот файл на страницах, к которым нужно ограничить доступ по паролю. Содержимое файла auth.php будет таким:

<?php

session_start();

if($_GET[‘do’] == ‘logout’){

unset($_SESSION[‘admin’]);

session_destroy();

}

if(!$_SESSION[‘admin’]){

header(«Location: enter.php»);

exit;

}

?>

Теперь вместо этой конструкции мы в файле admin.php просто подключим файл auth.php:

<?php

require «auth.php»;

?>

И на любой странице, к которой мы хотим ограничить доступ, теперь достаточно будет подключить этот файл таким способом.

Заключение

На этом наш урок завершен, мы выполнили поставленную в уроке задачу — написали свою простенькую систему авторизации. Конечно, как говорилось выше, для серьезных проектов такая система авторизации мало подходит, поскольку пользователей у нас может быть больше одного и хранить их нужно в БД. Да и шифрование пароля функцией md5() часто также бывает неэффективно, поскольку существуют сервисы с базами хешей… но для нас главное было понять принцип построения системы авторизации, а строится она именно по такому принципу. Итак, урок окончен. До новых встреч.

киберсант-вебмастер

Автор: Кудлай Андрей

Редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.

E-mail: contact@webformyself.com

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать веб-приложение на PHP с полного нуля

Получить курс сейчас!

Разработка веб-приложения на PHP

Скачайте видеокурс и узнайте, как создать веб-приложение на PHP

Скачать

Понравилась статья? Поделить с друзьями:
  • Сценарий выкупа невесты прикольный на первом этаже
  • Сценарий дня рождения юлии
  • Сценарии торжеств балов презентаций
  • Сценарий выкупа невесты медицинская тематика
  • Сценарий дня рождения шрек