Доброго времени суток дорогой читатель Блога RS! Как я и обещал, сегодня последний пост из цикла статей "Разработка блога с нуля". Все следующие посты будут посвящены улучшению написанного нами проекта. В этом посте нам предстоит написать авторизацию для нашей админ панели. Какой файл мы будем паролить?
Как мне кажется, нам необходимо запаролить лишь один файл, а именно index.php, так как лишь в нем производится подключение к базе данных. Если вызвать, отдельно, кусочки кода, которые мы подключаем из папки moduls, ничего не произойдет, так как все они требуют подключения к БД. Так что, с помощью этих кусочков, нельзя навредить блогу! Значит паролить их вовсе не обязательно.
Так как мы будем использовать этот подключение к БД уже в двух файлах ( в index.php и login.php ) то будет разумнее вынести скрипт подключения в отдельный файл. Так же мы сейчас создадим в этом скрипте переменную в которой будем хранить адрес нашего блога ( в виде http://адрес_блога.ru ). Сначала вынесем скрипт, потом я объясню зачем нам нужна переменная с адресом.
<?php
$nameDB = "blog";//Название БД
$nameSERVER = "localhost";//Сервер
$nameUSER = "root";//Имя пользователя БД
$passUSER = "";//Пароль пользователя БД
mysql_select_db($nameDB, mysql_connect($nameSERVER,$nameUSER,$passUSER));
if(isset($_GET['server_root'])){$server_root = $_GET['server_root'];unset($server_root);}
if(isset($_POST['server_root'])){$server_root = $_POST['server_root'];unset($server_root);}
$server_root = "http://yoururl.ru/";
?>
Сохраните этот кусочек кода в отдельном файле ( я этот файл назвал db.php и поместил в папку с модулями ) После удалите этот скрипт из файла index.php и вместо него вставьте следующий код
//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)
include("moduls/db.php");
//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)
Теперь поясню три новых строчки в файле db.php. Строчки
if(isset($_GET['server_root'])){$server_root = $_GET['server_root'];unset($server_root);}
if(isset($_POST['server_root'])){$server_root = $_POST['server_root'];unset($server_root);}
позволят нам удалить переменную если ее кто-то попытается создать GET или POST запросом. Сама же переменная с адресом нужна нам для того, что бы определить, идет ли авторизация с нашего блога, а не с постороннего сервера. Такая защита может уберечь наш блог от взлома, ну если быть точнее, то помогает нам, администраторам и программистам, в это верить
Для начала хочу сказать следующее: в БД мы будем хранить зашифрованный пароль с помощью функции php md5(). Админский логин и пароль мы пропишем в ручную. Я поставлю следующие данные:
Логин: admin
Пароль: 123456
Зашифрованный пароль будет выглядеть так:
e10adc3949ba59abbe56e057f20f883e
То есть если пароль 123456 пропустить через функцию md5 то получится вот такой зашифрованный пароль.
Приступим. Заходим в phpMyAdmin и создаем новую таблицу:
Авторизация будет простенькой, поэтому трех полей нам достаточно. Заполняем поля:
И вставляем в ручную одну строчку в таблицу
Сама авторизация представляет собой создание глобальной переменной $_SESSION. То есть если эта глобальная переменная есть, то пользователь авторизован, стало быть скрипт должен проверить, создана ли она ( глобальная переменная ). Если да то ничего не делать, если же нет, то перекинуть на файл login.php.
Перед тем как вызывать глобальную переменную $_SESSION, необходимо стартовать сессию, а именно прописать session_start(); Если этого не сделать, то глобальная переменная $_SESSION просто не будет работать!
В общем вот скрипт который необходимо вставить сразу после подключения к БД в index.php
//СКРИПТ ПРОВЕРКИ АВТОРИЗАЦИИ
if(isset($_GET['logSESS'])) {$logSESS = $_GET['logSESS'];unset($logSESS);}
if(isset($_POST['logSESS'])) {$logSESS = $_POST['logSESS'];unset($logSESS);}
session_start();
$logSESS = $_SESSION['$logSESS'];
if(!isset($logSESS))
{
header("location: login.php");
exit;
}
//СКРИПТ ПРОВЕРКИ АВТОРИЗАЦИИ
Так как значение глобальной переменной $_SESSION переносится в переменную $logSESS, то нам необходимо пресечь попытку создать эту переменную ( $logSESS ) иными способами ( я имею введу предотвратить создание этой переменной с помощью GET и POST запроса ). Именно эту функцию выполняют первые две строчки скрипта.
Далее мы стартуем сессию, и проверяем существует ли глобальная переменная $_SESSION. Если нет, то переносим пользователя на страницу авторизации.
Давайте для начала создадим шаблон. Шаблон представляет собой обычную форму с двумя текстовыми полями
<table width="600px" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td valign="top" align="center">
<form action="login.php" method="post" name="form">
<br>
<input style="width:150px;" name="loginDB" type="text" value="Логин">
<br>
<input style="width:150px;" name="passDB" type="password" value="Пароль">
<br><br><input type="submit" value="Авторизация">
</form>
</td>
</tr>
</table>
Тут нет ничего сложного. Мы не раз создавали подобные шаблоны. Назовем этот шаблон login.html и поместим в паку с шаблонами
Давайте для начала создадим функцию которая нам выдаст форму авторизации. Создаем новый файл, называем его login.php и помещаем его в папку admin
<?php
//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)
include("moduls/db.php");
//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)
//АВТОРИЗАЦИЯ
//место для кода авторизации
//АВТОРИЗАЦИЯ
//мета теги
$header_title = "Авторизация";
$header_metaD = "Авторизация";
$header_metaK = "Авторизация";
//мета теги
function form_author()//функция подключения формы
{
$sm_read = file("templates/login.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его
return $sm_read;//выводим результат
}
$txt = form_author();//вызываем функцию подключения формы
include("templates/index.html");//главный шаблон
?>
В этом файле мы подключаемся к БД ( в самом вверху ). Далее я оставил место для скрипта авторизации ( что бы было проще объяснить куда вставить скрипт который я выложу ниже ) После мы объявляем мета теги, и создаем нашу функцию.
Функция сама по себе очень не сложная, тут производится подключение шаблона, и не более того. Предпоследняя строчка сохраняет результат функции в переменную $txt. Ну и последняя строчка подключает главный шаблон.
Сейчас если вы попытаетесь проникнуть в админскую панель блога, но Вас перекинет на вот такую страницу
Теперь я Вам выложу сам скрипт авторизации ( в коде имеет комментарий почти каждая строчка ), и немного прокомментирую его ниже
//АВТОРИЗАЦИЯ
//уничтожаем переменную с логином и паролем которые были созданы путем ввода их в строку
if (isset ($_GET['loginDB'])) {$loginDB = $_GET['loginDB'];unset($loginDB);}
if (isset ($_GET['passDB'])) {$passDB = $_GET['passDB'];unset($passDB);}
//заносим в отдельные переменные логин и пароль присланных с помощью post запроса
if (isset ($_POST['loginDB'])) {$loginDB = $_POST['loginDB'];}
if (isset ($_POST['passDB'])) {$passDB = $_POST['passDB'];}
if(isset($loginDB) AND isset($passDB))//если существуют логин и пароль
{
if(preg_match("/^[a-zA-Z0-9_-]+$/s",$loginDB) AND preg_match("/^[a-zA-Z0-9]+$/s",$passDB))//проверяем их на корректность ввода с помощью регулярных выражений
{
$prov = getenv('HTTP_REFERER');//определяем страницу с который пришел запрос
$prov = str_replace("www.","",$prov);//удаляем www если есть
preg_match("/(http\:\/\/[-a-z0-9_.]+\/)/",$prov,$prov_pm);//чистим адресс от лишнего, нам необходимо добиться ссылки вот такого вида http://xxxx.ru
$prov = $prov_pm[1];//заносим чистый адрес в отдельную переменную
$server_root = str_replace("www.","",$server_root);//удаляем www если есть
if($server_root == $prov)//если адрес нашего блога и адрес страницы с которой был прислан зарос равны
{
$passDB = md5($passDB);//шифруем введенный пароль
$resultlp = mysql_query("SELECT login,pass FROM user WHERE login='$loginDB'");//выводим из базы данных логин и пароль
$log_and_pass = mysql_fetch_array($resultlp);
if($log_and_pass != "")//если был выведен результат из БД
{
if($loginDB == $log_and_pass[login] AND $passDB == $log_and_pass[pass])//если введенная информация совпадает с информацией из БД
{
session_start();//стартуем сессию
$_SESSION['$logSESS'] = $log_and_pass[login];//создаем глобальную переменную
header("location: index.php");//переносим пользователя на главную страницу
exit;
}
else//если введеная инфо не совпадает с инфо из БД
{
header("location: login.php");//переносим на форму авторизации
exit;
}
}
else//если не найдено такого юзера в БД
{
header("location: login.php");//переносим на форму авторизации
exit;
}
}
else//если запрос был послан с другого адреса
{
header("location: login.php");//переносим на форму авторизации
exit;
}
}
else//если введены не корректный логин и пароль
{
header("location: login.php");//переносим на форму авторизации
exit;
}
}
//АВТОРИЗАЦИЯ
Этот кусочек кода вставляется в файле login.php вместо вот этих строк
//АВТОРИЗАЦИЯ
//место для кода авторизации
//АВТОРИЗАЦИЯ
Как работает скрипт? Для начала уничтожает переменные, с логином и паролем, созданные методом GET ( если такие имеются ). После идет проверка на корректность логина и пароля с помощью регулярных выражений.
Так же производится формирование адреса с которого пришел пользователь. То есть адрес, с которого пришел пользователь, должен быть таким:
http://yoururl.ru/login.php
а после формирование, вот таким:
http://yoururl.ru/
Этот адрес сравнивается с адресом из переменной $server_root которую мы объявили в подключение к БД ( файл db.php )
Далее идут проверки на совпадения введенного пароля и пароля из БД. Только после этих проверок создается глобальная переменная, и пользователь перенаправляется на главную страницу админ панели.
Если же хотя бы одно условие не сработает, то пользователя перенаправят обратно к форме.
Теперь если ввести в окно формы
логин - admin
пароль - 123456
То Вас перенесет в админ панель. Если же вы введете неправильный логин или пароль, Вас перекинет обратно к форме.
Сейчас нам придется править главный шаблон админ панели, мы вставим в него ссылку на скрипт выхода, поэтому мы еще заодно пропишем в шаблон ссылку на главную страницу админ панели. Добьемся того, что бы при щелчке по логотипу в админ панели, нас переносило на главную страницу. ( Это конечно не обязательно )
Вот новый кусочек кода который я вставил, вместо старого, в шаблон index.html
<!--ЛОГО-->
<div class="logo">
<div class="logoP">
<p style="padding:3px;"><a style="font-weight:100;" href="/index.php">Добро пожаловать в админ панель</a> <a href="exit.php" style="font-size:10px;font-weight:100;">(Выход)</a></p>
</div>
</div>
<!--ЛОГО-->
Теперь создадим новый файл, назовем его exit.php и поместим его в папку admin. Вот код файла
<?php
session_start();//стартуем сессию
unset ($_SESSION['$logSESS']);//удаляем зарегистрированную глобальную переменную
session_destroy();//уничтожаем сессию
header("location: ../");//перебрасываем на главную страницу пользовательской части блога
exit;
?>
Тут каждая строчка имеет комментарий, так, что разберетесь
Ну чтож, на этом я заканчиваю разработку простейшей CMS на php. Если это первый пост который Вы читаете на этом блоге, то вот список всех статей посвященные разработки блога с нуля. Совсем скоро открою рубрику "Улучшения" и продолжу мучить наш проект Так что подпишитесь на новости, и ждите новые посты!
Если у Вас возникли какие либо вопросы, то не стесняйтесь, задавайте их, буду рад ответить ( если конечно в силах ответить на Ваш вопрос ).
Удачи Вам, на сегодня у меня все!
Исходник |
А можно ли сделать чтобы в строке ввода(URL) не показывался путь до скрипта, ну к примеру http://test1.ru/moduls/login.php, а надо чтобы просто показывалось http://test1.ru... Просто в статье посмотрел там идет проверка лишь на то чтобы сравнить с чего зашли...
Извините, если не по теме написал...
Файл login.php должен находится в папке admin а не в moduls. Поэтому путь будет выглядеть вот так
http://test1.ru/admin/login.php
А что бы показывалось
http://test1.ru/
необходимо переделывать всю механику авторизации.
P.S.: Откуда у Вас рождаются подобные вопросы? =D
Меня посетила идея тоже заняться написанием CMS для своих нужд, для учебы...изучать PHP я начал недавно...на уровне SAX,DOM,SimpleXML - примерно где-то тут сейчас я :) так что если возникнут глупые вопросы, прошу не ругаться строго :) Думаю с завтрашнего дня плотно засяду на вашем блоге и буду основательно смотреть, изучать, писать...так что комменты будут везде, я думаю :))))
Хотелось бы задать пару вопросов:
1) Не думали ли вы об объектно-ориентированном подходе в создании, а не о процедурном?
2) Не планируется ли выпуск скринкастов? А то вещь весьма популярная...взять тот же Ютуб - пробовал найти что-нибудь по созданию cms - всякая чушь попадается, ничего путевого из русско-язычного...Есть забугорные (там как раз используется ООП), но это забугорные. Они там так быстро говорят что мозг не успевает переводить слова :)))
Вот примерно пока так :)
1. ООП по сути это объедение логики в один объект для удобной работы с ним в дальнейшем. В проекте не такая уж сложная логика, что бы ее объединять в классы.
Так же, на сколько мне известно, классами пользуются в основном в проектах над которыми работают несколько программистов, что бы один программист не разбирался в работе кода другого программиста, а просто пользовался возможностью программы. Так вот над этим проектом работает один программист, стало быть классы тут не к чему. Пользоваться php как ООП (именно в этом проекте), лишь потому, что это возможно, не вижу смысла (ИМХО)
2. Записывать видео уроки мне мешает две вещи.
Первая - я совершенно не умею говорить с аудитории =) постоянно теряю мысль.
Вторая - В данный момент слишком мало свободного места на жестком диске.
Как бы да. В этом Вы правы - ООП используется для командной работы...хотя порой конечно с ООП работать более удобнее -свойства, методы, __autoload() - вообще рулят! :) Хотя довольно интересное решение совместить 2 подхода...
"Первая - я совершенно не умею говорить с аудитории =) постоянно теряю мысль."
Человеческий фактор :) Хотя это по сути тоже самое что и самому себе пересказывать что мы делаем - проговаривая мысли вслух. Сразу вспоминается k0stix с его ООП и чайком :)))))))
а скрыть путь до скрипта я хочу для безопасности)))
А так спасибо вам за этот блог, он шикарен, все понятно и легко, главное включить голову, а не просто копи-паст)))
if($server_root == $prov){...}
Проверьте значение обоих переменных, перед сравниванием.
Например если Ваш адрес в адресной строке вот такой:
http://s-zl.ru/admin/login.php
То в переменной server_root должно находится следующее значение
http://s-zl.ru/
Так же обратите внимание на слэш (у значение переменной server_root) в конце домена.
Большое спасибо вам за ваш блог! Долго искал его! И вот нашел, сделал кмс! Диплом почти готов! Обязательно ссылку укажу в списке лит-ры! Теперь буду редактировать стили! Кстати, у вас в стилях не прописано форматирование текста статей, если большая статья, то текст идет в одну строку, а не переносится.
1. Логин администратора содержит не правильный набор символов, то есть что-то кроме букв английского алфавита, цифр, нижнего подчеркивания "_" и тире "-".
2. Пароль содержит не допустимые символы, а именно что-то кроме английских букв и цифр.
3. Переменные server_root и prov не совпадают. В переменной server_root содержится домен сайта, а в переменной prov содержится имя домена с которого посылали логин и пароль.
4. Если в базе данных нет запрашиваемого пользователя.
5. Если введенный логин и пароль не совпадают с данными хранящихся в базе данных.
Проверьте все используемые переменные, это единственный способ узнать в чем причина.
Напишу способ как определить переменные.
1. Сразу после:
2. Уберите код который внедряли в предыдущем пункте, и пропишите сразу после:
3. Уберите код который внедряли в предыдущем пункте, и пропишите сразу после:
4. Уберите код который внедряли в предыдущем пункте, и вместо убранного кода следующее:
Если найдете в чем причина сообщите, думаю другим будет полезна данная информация..
в хромі виводить "Ошибка 310 (net::ERR_TOO_MANY_REDIRECTS): Обнаружено слишком много переадресаций."
в мазілі "Firefox визначив, що сервер перенаправляє запит на цю адресу таким чином, що він ніколи не завершиться."
Вообще циклить не должно, использую данный скрипт на своем блоге, и ничего не циклит...
Только вот возникла проблемка, при входе в админ панель не перекидывает на форму авторизации, открывается страница login.php с содержимым шаблона index.html. Никак не могу разобраться почему не загружается login.html. Может вы подскажете в чем может быть причина :)
Так что загружаться должен именно index.html, в котором будет содержаться шаблон login.html
Для чего это нужно?
p.s. Спасибо что дали мне повод обратить внимание на код. В данных строчках была копипастная опечатка. Надо было написать не
if (isset ($_GET['loginDB'])) {$loginDB = $_POST['loginDB']; unset($loginDB);}
а
if (isset ($_GET['loginDB'])) {$loginDB = $_GET['loginDB']; unset($loginDB);}
Почитайте про флаги у регулярных выражений, узнаете очень много интересного =)
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at C:\OpenServer\domains\localhost\acp\index.php:1) in C:\OpenServer\domains\localhost\acp\index.php on line 7
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\OpenServer\domains\localhost\acp\index.php:1) in C:\OpenServer\domains\localhost\acp\index.php on line 7
Warning: Cannot modify header information - headers already sent by (output started at C:\OpenServer\domains\localhost\acp\index.php:1) in C:\OpenServer\domains\localhost\acp\index.php on line 11
Так же проблема может быть в кодировке.. Вы можете наблюдать вот такие символы в самом верху вашего сайта:
п»їп»ї
Если это так, то Вам необходимо сменить кодировку. Вот статья по этому поводу:
http://rio-shaman.ru/index.php?blog=133
Самая распространенная проблема это несовпадение переменной server_root и переменной prov. Особенно часто данная проблема видна если адрес хоста имеет приблизительно вот такой вид:
http://localhost/website/
Ибо в переменной prov образуется вот такие данные:
http://localhost/
а в переменной server_root лежат вот такие:
http://localhost/website/
Вот ссылка на цикл http://rio-shaman.ru/sozdat-blog/
Переменная txt выводится посредством оператора echo в шаблоне index.html. Переменная никак не привязана ни к диву ни к классу.
Видимо из-за слэша не работает, а вот как его убрать или наоборот добавить не пойму.
Вообще изначально не работало из-за того то в бд ставил пароль не зашифрованный, когда убрал в пхп мд5 все заработало, потом поставил шифр в бд и в пхп, работать перестало,в ернул обратно и тоже уже не работает даже без мд5, видать теперь проблема с слэшем?
1. /moduls/db.php
2. /admin/moduls/db.php
В каждом из этих файлов есть переменная $server_root. В данной переменной и нужно написать адрес с слешем в конце
Инструкция "что делать" есть вот в этом сообщение
Воспользовался ВАШЕЙ разработкой, для дополнительной защиты... Слегка подредактировал, дописал... в процессе, заметил, что шифрование пороля в md5, не происходит, то есть, ели через базы, прописываю пароль в md5, то пароль становится не читаемым, для админки! А так очень даже интересное решение, на "инъекции"- вроде как проходит, в смысле защишено, а вот вопроса-
1. Насколько сильна защита , в пределах разумного конечно?
2.Чем и как могу отблагодарить, за идею, которой надеюсь воспользуюсь?
Спасибо.
2. Не совсем понял вопроса... что за идея?
Заранее спасибо за помощь.
login: admin
pass: e10adc3949ba59abbe56e057f20f883e
Теперь по-поводу того что выводится:
Если пароль вводить 123456 то выводится цифра 1, то есть как я понял введеная инфо не совпадает с инфо из БД
Если пароль вводить e10adc3949ba59abbe56e057f20f883e то выводится цифра 4, то есть получается введены не корректный логин и пароль
Вот такая запутанная ситуация(((
Вывелась следующая строка:
Действительно в БД убрал пробел в конце и ВСЕ ЗАРАБОТАЛО!!!!))))
Скорее всего Вам будет достаточно заменить в коде вот такую строку
Доброго времени суток.
Если под вставкой картинки подразумевается загрузка их на сервер и отображение ее в визуальном (или в подобном) редакторе, то для этого нужно пилить много кода. Ну или можно воспользоваться каким-нибудь менеджером загрузок, который написан на js.
Мне не приходилось делать подобный функционал, поэтому что-то конкретно сказать не могу.
Более простой способ - это загрузчик изображений отдельно, а в визуальный (или подобный) редактор вставлять просто ссылку на загруженную картинку.
if(isset($_GET['server_root'])){$server_root = $_GET['server_root'];unset($server_root);}
if(isset($_POST['server_root'])){$server_root = $_POST['server_root'];unset($server_root);}
Например открыв вот такую страницу
Эти строчки пытаются получить, важные для скрипта, данные из непроверенного источника, и почистить их (Должен сказать, что это не удачное и не логичное решение. В 2012-ом год, к сожалению, мне казалось иначе)
Данная настройка была удалена в php 5.4.0, а в 4.2.0 по умолчанию отключена.
Как выяснилось, условие не выполнялось из-за того, что переменная $server_root была пустая.
Я присвоил этой переменной значение заново, вот так:
Естественно, в файле db.php я убрал эти строки
Вопрос такой, есть ли смысл от проверки, которую я выполняю
Привет из 2019, спасибо за качественный контент!
Некоторые функции mysql удалили, теперь нужно использовать mysqli.
вот такой код получился у меня, после всех поправок (только недавно начал учить php и mysql, так что он явно не идеален) :
login.php -
db.php -