Парольная защита
Автор: | Артемьев Сергей Игоревич |
ICQ: | 438856621 |
email: | _spin_@bk.ru |
Одна из основных аксиом защиты информации гласит - "комфортность системы обратно пропорциональна её защищённости". Это значит, что при выборе системы защиты необходимо найти оптимальное соотношение сложности защиты и удобства работы пользователей.
С другой стороны, разработка и внедрение защиты требует определённых затрат сил и средств. Следовательно, надо разумно подходить к проектированию защиты. Проще говоря, не надо делать сложную и дорогостоящую систему защиты, если на сайте не хранится ничего ценного. Ни один злоумышленник не полезет ломать вашу домашнюю страничку, сайт-визитку небольшой компании или сайт детского сада.
В предыдущем уроке мы рассматривали авторизацию средствами Web-сервера (Basic-авторизация). Наверное, это самый лёгкий и самый безопасный способ ограничения доступа к ресурсам. Однако, сопровождение такого механизма достаточно трудоёмко, особенно при большом количестве пользователей с различными правами. Кроме того, не все сервера позволяют использовать HTTP-авторизацию.
Более популярная альтернатива - парольная защита. Смысл её в том, что на сервере хранятся списки пользователей и соответствующие им логины, пароли и права доступа. При первом обращении к сайту пользователь вводит логин/пароль и получает доступ к ресурсам. Сервер "запоминает" пользователя и не спрашивает пароль до следующего открытия сессии (перезапуска браузера).
Организация парольной защиты целиком и полностью ложится на плечи программиста. Разработчик должен сам обеспечить безопасность хранения списков пользователей, проверку логинов/паролей, сохранение контекстов безопасности и их повторное использование. Под контекстом безопасности здесь понимается набор параметров, однозначно определяющих пользователя (как минимум это логин, пароль и идентификатор сессии).
Рассмотри пример реализации простейшей парольной защиты. Создадим файл logon.php
<div> <?php $login = isset($_GET['login'])?$_GET['login']:''; $passwd = isset($_GET['passwd'])?$_GET['passwd']:''; if($login != '' || $passwd != '') { if($login == 'admin' && $passwd == 'megaPass') echo 'Доступ разрешен'; else echo 'Доступ запрещен!'; } else echo 'Введите логин и пароль'; ?> </div> <form action="logon.php" method="get"> <input type="text" value="" name="login" /> <input type="password" value="" name="passwd" /> <input type="submit" value="вход" /> </form>
При нажатии на кнопку "вход" данные формы будут отправлены на сервер, там скрипт проверит введённые логин и пароль и если они равны "admin" и "megaPass" соответственно - отобразит сообщение, что вход разрешен. Если логин или пароль не верны - пользователь увидит предупреждающее сообщение.
Первый недостаток этого скрипта: передача данных методом GET. При использовании этого метода данные передаются непосредственно в адресе, а значит видны даже невооруженным глазом. Например, если вы ввели правильные логин и пароль, то в адресной строке увидите
http://localhost/logon.php?login=admin&passwd=megaPass
Второй недостаток: имена пользователей и пароли зашиты прямо в код. Это значит, что для добавления новых пользователей вам надо будет постоянно менять код файла. А представьте себе, какого размера будет файл, если у вас на сайте хотя-бы тысяча зарегистрированных пользователей... Списки пользователей лучше всего хранить в отдельном файле, а лучше в базе данных, т.к. злоумышленнику файл украсть намного проще, чем добывать что-то из базы данных.
Третий недостаток: результаты входа пользователя не запоминаются, т.е. достаточно обновить страницу и вас снова попросят ввести пароль.
Итак, рассмотрим способы устранения этих недостатков.
Скрыть передаваемые данные проще всего используя метод передачи POST. В этом случае браузер сам (скрытно от пользователя) передаст серверу все необходимые данные и перехватить их можно будет только специальными программами из арсенала IT-специалистов, программистов или хакеров.
Как говорилось выше, списки пользователей надо хранить отдельно. Создадим таблицу в тестовой базе данных:
CREATE TABLE `smplusers` (
`user_id` int(11) NOT NULL auto_increment,
`user_name` varchar(50) NOT NULL,
`user_login` varchar(50) NOT NULL,
`user_password` varchar(50) NOT NULL,
`reg_date` datetime NOT NULL,
PRIMARY KEY (`user_id`)
)
и добавим в неё несколько записей пользователей:
INSERT INTO smplUsers
(user_name, user_login, user_password, reg_date)
values
('Иванов И.И.', 'ivanov-i-i', 'pass1', NOW()),
('Петров П.П.', 'petrovich', 'pass2', NOW()),
('Сидоров С.С.', 'sidorov', 'pass3', NOW())
Обратите внимание, что оператор INSERT допускает одновременное добавление в таблицу сразу нескольких записей, при этом данные перечисляются блоками через запятую.
Теперь изменим logon.php таким образом, чтобы имя пользователя и пароль корректно проверялись непосредственно в базе данных:
<?php
// здесь подключаемся к базе данных
// $link - ссылка на подключение
$link = mysql_connect('localhost', 'db_user', 'db_passwd');
mysql_select_db('db_name', $link);
?>
<div> <?php
$login = isset($_POST['login'])?$_POST['login']:'';
$passwd = isset($_POST['passwd'])?$_POST['passwd']:'';
$login = mysql_real_escape_string($login);
$passwd = mysql_real_escape_string($passwd);
if($login != '' || $passwd != '')
{
$sql = "SELECT * FROM smplUsers
WHERE user_login = '$login'
AND user_password = '$passwd'
LIMIT 1";
$qry = mysql_query($sql, $link);
if($qry)
{
if(mysql_num_rows($qry) > 0)
{
echo 'Доступ разрешен<br />' . "\n";
$row = mysql_fetch_array($qry);
echo 'Пользователь: ' . $row['user_name'];
}
else
echo 'Доступ запрещен!';
}
}
else
echo 'Введите логин и пароль';
?>
</div> <form action="passes.php" method="post" enctype="application/form-data">
<input type="text" value="" name="login" />
<input type="password" value="" name="passwd" />
<input type="submit" value="LogIn" />
</form>
Теперь логин и пароль передаются скрытно, а учётные данные очень просто изменить, отредактировав таблицу в базе данных. Остался последний штрих - научить сервер запоминать факт регистрации. Проще всего сделать это при помощи механизма сессий. Внесём необходимые изменения:
<?php // открываем сессию
session_start(); if(!$_SESSION['user_id']) $_SESSION['user_id'] = -1; // здесь подключаемся к базе данных ...
?>
<div> <?php if($_SESSION['user_id'] == -1) {
$login = isset($_POST['login'])?$_POST['login']:'';
...
if(mysql_num_rows($qry) > 0)
{
echo 'Доступ разрешен<br />' . "\n";
$row = mysql_fetch_array($qry);
echo 'Пользователь: ' . $row['user_name']; $_SESSION['user_id'] = $row['user_id']; $_SESSION['user_name'] = $row['user_name'];
}
... } else echo 'Здравствуйте, ' . $_SESSION['user_name'];
?>
</div> ...
Теперь сервер будет запоминать каждого пользователя, успешно вошедшего в систему, а при следующем обновлении страницы будет выводиться приветственное сообщение.
Это скрипт - лишь пример организации парольной защиты, пусть и вполне функциональный. Сделать из него практически ценный образец можно, добавив проверку вводимых данных, функции шифрования, восстановения пароля, завершения сессии и др.