Forum Webscript.Ru
Программирование => PHP => Тема начата: Rodent от 12 Марта 2004, 00:02:31
-
Доброе время суток.
Мне хотелось бы спросить совета и узнать насколько правильна моя система авторизации (плюсы и минусы). А если есть возможность объяснить в чем моя ошибка или как улучшить.
Итак структура:
файл admin.php
$users["demo"]=md5("demo");
global $userName, $userPass;
session_start();
$userName=trim($_POST["user"]);
$userPass=trim($_POST["pass"]);
$userEnter=$_POST["submit"];
if ($userEnter=="Войти"):
if ($userName=="") $error[]="Не заполнено поле \\"Имя\\"";
if ($userPass=="") $error[]="Не заполнено поле \\"Пароль\\"";
if ($users[$userName]!=md5($userPass)) $error[]="Неверный пароль";
if (!isset($error)) {
session_register("userName");
session_register("userPass");
$enter=1;
}
else $enter=0;
endif;
if (isset($error) && $error!=""):
echo "Ошибка";
foreach ($error as $value) echo "- $value
";
endif;
if ($enter==0):
?>
elseif ($enter==1):
echo "Вошли !!!";
endif;
?>
ну а дальше во все файлы где требуется авторизация я require данный файл. При этом содержимое файлов примерно такое:
$enter=0;
require ("admin.php");
if ($enter==1):
// а тут уже все что угодно
endif;
?>
Вот вроде все...
С уважением, Николай
-
Народ я тут инфу накопал по своему вопросу и сейчас в ней разбераюсь, но все равно оцените (на плюсы и минусы) данный код, и как его сделать более правильным без использования БД но с использованием и куки и сессии.
- http://forums.webscript.ru/showthread.php?s=&threadid=6822 (http://forums.webscript.ru/showthread.php?s=&threadid=6822)
- http://phpclub.ru/talk/showthread.php?old=1&threadid=32810 (http://phpclub.ru/talk/showthread.php?old=1&threadid=32810)
-
Rodent:
но все равно оцените (на плюсы и минусы) данный код
если пхп работает с register_globals = On то взломать можно (вроде).
Например замени свою форму на такую:
и введи в поля логин/пароль - new_user/1
c4ca4238a0b923820dcc509a6f75849b - это md5("1");
-
Так мой сервак, просто так переменные из формы брать не будет их надо сначала объявить типа
$users[]=$_POST["users"];
и тому подобное...
Хотя я могу и заблуждаться...
-
Rodent:
global $userName, $userPass;
Что ты этим хочешь сказать?
Rodent:
if (!isset($error)) {
session_register("userName");
session_register("userPass");
$enter=1;
}
else $enter=0;
endif;
Красиво написано :) Ты уж опредились как-нибудь.
Rodent:
if (isset($error) && $error!=""):
Ну кто же так делает? Ай-ай-ай.. :(
Обьяви $error как пустой массив в начале скрипта. И проверяй:
if (count($error))
-
Rodent:
Так мой сервак, просто так переменные из формы брать не будет их надо сначала объявить типа
я же написал, что эта дыра только при register_globals = on
-
Neter
1. я их глобализировал , т.к. мой сервак начинал ругаться. выдавал типа Warning: Unknown(): Your script possibly relies on a session side-effect which existed until PHP 4.2.3. Please be advised that the session extension does not consider global variables as a source of data, unless register_globals is enabled. You can disable this functionality and this warning by setting session.bug_compat_42 or session.bug_compat_warn to off, respectively. in Unknown on line 0"
2. с этим я не понял с чем мне надо определиться???
3. опять не понял в чем моя ошибка?
-
Rodent Переменные "глобализируют" только внутри функций, какая версия РНР?.
2.
Либо ты пишешь так if (expr){ }
Либо if (expr):
endif;
3. Добавь в начало $error = array();
И проверяй как if (count($array))
Почему? Потому что так - правильно.
[OFF]Люди зацените часть сырца РНРшного сайта http://www.php.net/include/site.inc[/OFF]
-
Neter
1. Apache 1.3.26 PHP 4.3.3
2. C этим тоже разобрался, спасибо что уточнил
3. Ну добавлю я $error=array();
Проверю if (count($array)), но чо мне это даст? каков будет ответ?
что вообще эта за структура count ($array) и что она мне дает?
-
Rodent Тьфу ты, не $array а $error, count($error) возвратит количество элементов массива, так правильней чем сначала искать есть ли эта переменная а потом сравнивать массив со строкой.
-
Neter
То есть если count($error) мне выдает 0, то можно продолжать работать?
Всем
Ладно я не много отвлекся от темы. может кто-нить еще даст советы по оптимизации данного вида авторизации. Или то что есть нормально?
-
Я под конец совсем запулся с сессиями.
как я понял, для того чтобы зарегистрировать переменную нужно написать
session_start();
session_register("user");
После этого данная переменная появляется в в сессии, но она пока без значения, теперь мы ей присваиваем значение
$user="admin";
по идее в сессии теперь находиться переменная user со значением admin. правильно???
Теперь. как мне добыть данную переменную на других страницах сайта???
Опять открыть сессию и зарегить переменную
session_start();
session_register("user");
теперь, по идее опять же, если написать
echo $user;
мне браузер должен вывести admin.
Я прав или нет??? сама схема работы сессии мной понята правильно???
-
И еще мне не совсем нравиться моя авторизация на других страницах сайта
$enter=0;
require ("admin.php");
if ($enter==1):
// а тут уже все что угодно
endif;
?>
Ситуация такая. что я допустим нормально зарегился на страничке авторизаторе, перехожу на другие защищенный странички где вставлена ссылка
reqiure (auth.php);
и допустим что авторизация не прошла. Тогда скрипт должен тут же прекратить долнейший вывод странички и перенаправить пользователя еще раз зарегиться.
-
Я не слишком много вопросов задаю???
я новичок в пхп, но я стараюсь, перед тем как задавать вопросы проникнуться данной проблемой.
Ну а в общем данный форум, мне кажется, для того и существует чтобы помогать таким как мне и делиться опытом.
Или я опять же не прав???
-
Rodent После товарища под ником "хах" твои вопросы как бальзам на душу :)
Я несколько подправил твой код.
auth.php
$users["demo"]=md5("demo");
session_start();
$error = array(); // Типа так надо :)
$_SESSION[\'username\'] = "";
$_SESSION[\'userpass\'] = "";
if (@$_POST["logon"]){ // @ Нужна для подавления ошибок . т.е. если человек не жмакнул кнопку
$userName = trim(@$_POST["user"]);
$userPass = trim(@$_POST["pass"]);
if ($userName=="") { $error[]="Не заполнено поле \\"Имя\\""; }
if ($userPass=="") { $error[]="Не заполнено поле \\"Пароль\\""; }
if (array_key_exists($username, $users) && $users[$userName]!=md5($userPass)) { $error[]="Неверный пароль"; } // @ тут нужна потому что если индекса с логином не окажется чтобы РНР не ругался.
if (!count($error)) {
$_SESSION[\'username\'] = $userName; // С переменными сесси гораздо удобней работать как с суперглобальным массивом.
$_SESSION[\'userpass\'] = $userPass;
}
}
if (count($error)){ // Если $error не пуст покажем его содержимое.
echo "Ошибка";
foreach ($error as $value) { echo "- $value
"; }
}
if (!$_SESSION[\'username\']){
?>
exit; // Вывести форму и закончить выполнение скрипта.
}
?>
test.php
require("auth.php");
?>
А вот тут уже что угодно :)
-
@ Нужна для подавления ошибок
Восхитительный пассаж.
Сообщения об ошибках - ЕДИНСТВЕННЫЙ способ для программиста узнать, что он написал кривую программу.
Однако вместо того, чтобы переписать ее, мы просто заткнем ей рот.
прелестно.
Сами же растим грабли. на которые потом со всей дури...
-
Огромное спасибо Neter
Опробывал... работает... даже разобрался...
Но теперь возникло еще пара вопросов.
Я тут на форуме выяснял, какая структура сайта более рациональна с точки зрения легкой смены дизайна и кода.
Ну так вот я пришел вот к такой схеме.
У меня есть файлы
index.php - это начальный файл к нему подключаются:
function.php - где собраны все функции, которые довольно-таки часто используются на сайте
design.php - сам дизайн сайта.
index.php
require ("function.php");
$page=$_GET["page"];
$pages["main"]=array("file"=>"main.php","menu"=>"menu01.php");
$pages["news"]=array("file"=>"news.php","menu"=>"menu02.php");
$pages["guest"]=array("file"=>"guest.php","menu"=>"menu03.php");
$pages["admin"]=array("file"=>"admin.php","menu"=>"menu04.php");
$menu=$pages[$page]["menu"];
$main=$pages[$page]["file"];
require ("design.php");
?>
Файл design.php как видно состоит из шапки неизменной, и таблицы разделенной на две части: меню и основная часть.
Теперь вопрос как мне сделать авторизацию на страницы вставляемые таким путем, так как естественно пхп ругается, потому что сессии должны запускаться до отправления чего-либо в браузер?
И еще при такой авторизации если у нас не задана сессионная переменная user, то задействуется функция exit, которая убивает все, но дизайн-то требует законченности.
Вот такие теперь у меня возникают вопросы.
-
RomikChef
а что ты предлагаешь???
-
RomikChef Рома, я знаю о твоём мнении насчёт этих собак, я это понимаю, но это тот случай когда подавление сообщения об ошибке оправдано. Насчёт @$users[$userName] - это мне и самому не нравится, просто не подумавши написал, впринципе это правильно и ничего страшного в этом нет, но на всякий случай я поправил код. Или ты где-то ошибку увидел? (вопрос с подковыркой ;) )
Rodent Дам тебе совет насчёт собак, никогда не используй их для функций и собственных переменных, НИКОГДА!
-
Neter
НЕТ собакам(@)! ДА отключению вывода ошибок в php.ini
НЕТ двойным кавычкам! ДА одинарным![не актуально]
НЕТ конструкциям типа $var==""! ДА функциям [p]isset[/p] и [p]empty[/p]
-
Rodent создавай новые топики для новых вопросов
-
Neter:
я знаю о твоём мнении насчёт этих собак
Ничего ты не знаешь!
Ни-Че-Го!
Ты сам-то почитай свои оправдания!
Вчера я был слишком уставший, чтобы заниматься разжевыванием азов.
Делаю это сейчас.
Вот смотри, я тебя, неуча, сейчас буду тыкать носом.
Наглядно показывать, что имея наглость с малыми знаниями иметь свое собственное мнение, ты сам расставляешь себе грабли.
@ Нужна для подавления ошибок . т.е. если человек не жмакнул кнопку
Твои слова?
А тебе известно о том, что переменная эта может быть не установлена, при том, что форма отправлена? Если просто нажать на ентер. Вот если бы у тебя не было собаки - ты бы этот момент увидел СРАЗУ! По нотайсу. Пришел бы на форум - а как это так - форма отправлена, а переменной нету. И тебе бы объяснили.
А собакой ты нотайс подавил. В переменных своих ты уверен. И ловил бы глюк хрен знает сколько времени.
воспитательная часть закончена. Переходим к практической.
Если надо проверить, есть такая переменная, или нет, то надо использовать функцию isset() и нотайсов не будет, и ясность во всем. Не выполняется условие? Значит, переменная не установлена. Копаем, почему. НО НЕ ЗАТЫКАЕМ ПРОГРАММЕ РОТ!
И не пишем программ, в которых ошибки являются их частью.
Хотя, по-моему, некоторые люди просто не в состоянии понять, что сообщения об ошибках сделаны ДЛЯ ПОМОЩИ, а не просто развлечение разработчиков, чтобы досадить несчастным программистам и их надо подавлять.
Если надо проверить, отправлена была форма, или нет, при условии, что форма одна на странице (что бывает в подавляющем большинстве случаев), достаточно проверить _SERVER[\'REQUEST_METHOD\']. Если форм много и все с одним экшеном, то нужно хидден поле, чтобы их отличить.
с $_POST["logon"] (вместо которого ты мне подсунул @$users) разобрались.
Далее.
@$_POST["user"]
Как мы уже проверили выше, фолрма пришла постом.
Значит, поля "юзер" и "пасс" в ней обязательно должны быть.
А вдруг их нету???
А если их нету, то это форс-мажорная ситуация! Это или хакер лезет, или ошибка какая-то. Так программисту НАОБОРОТ!!!! НАДО. ОБ. ЭТОМ. ЗНАТЬ!!!
Что форма передана. а переменные почему-то - нет.
Ну я совершенно не представляю, как можно быть настолько страусом.
Ты для заказчика что ли пишешь? Лишь бы скинуть? Ну так отключи сообщения об ошибках ВООБЩЕ ВСЕ. И дело с концом.
А если ты нормальный программист, если тебя волнует работоспособность программы, то ты должен
1. написать ее так, чтобы она в штатном режиме никаких ошибок не выдавала. Чтобы ошибки не были ее частью.
2. ТЩАТЕЛЬНО изучать все сообщения об ошибках, буде таковые появятся. Иисправлять.
ПРИЧИНУ исправлять, бестолочь! а не сообщение. Болезнь лечить, а не симптом!
3. Скрывать сообщения об ошибках от юзера - они ему не нужны.
display_errors=off
ПОКАЗЫВАТЬ сообщения программисту
log_errors=on
Дальше.
Этот твой @$users
Вижу - исправил.
Опять же - за что ты не любишь примитивную функцию isset?
она гораздо короче, чем твой аррай кей екзистс и удобнее.
Тебе кажется, что обе эти функции все равно лишние?
Ну так учти, что в массиве никто логины с паролями не хранит, и весь этот пример притянут за уши.
то есть, проверять существование ключа одновременно со сравнением значения требуется на самом деле достаточно редко.
В нормальном же применении массивов попытка обратиться к несуществующему индексу - ОШИБКА! Важная ошибка, о которой должен знать программист.
О которой он будет знать, если не затыкает своей программе рот.
-
Rodent
Я тебе отвечу.
Однако предупреждаю - если начнутся стоны или обидки, то тема будет немедленно закрыта.
Я не обсуждаю здесь вопросы твоей гениальности ли убогости. Такое мнение может возникнуть ТОЛКО если
1. ты считаешь себя гением, а свое решение гениальным
2. твое рещение критикуется.
При адекватной же самооценке факт критики воспринимается не как попытка наехать, а как попытка помочь.
Сейчас ты наткнулся на первые грабли системы "запихнуть весь сайт в один файл". Оставив в стороне эстетическую сторону вопроса, я лишь скажу, что граблей таких будет много.
К примеру:
Вот на этом сайте выводится в заголовке окна (в теге title) название темы. А в твоем это сделать затруднительно.
Заплаток можно будет наставить много. Из-за них твой файл индекс, который не делает НИЧЕГО кроме того, что показывает другие файлы юзеру, будет ВСЕ ВРЕМЯ разрастаться.
Я считаю, что лучше обойтись без него вовсе. Без лишнего кода, без лишнего файла, без лишнего параметра в адресе.
Возьми, да раздели свой design.php на две части - верх и низ.
И подключай в каждом скрипте в нужных местах.
Таким образом разом снимутся все проблемы. Сохранится легкость смены дизайна. И скрипты приобретут гибкость.
-
$userName = trim(@$_POST["user"]);
$userPass = trim(@$_POST["pass"]);
if ($userName=="") { $error[]="Не заполнено поле \\"Имя\\""; }
if ($userPass=="") { $error[]="Не заполнено поле \\"Пароль\\""; }
заменяем на
if (!$userName=trim($_POST["user"])) $error[]=\'Не заполнено поле "Имя"\';
if (!$userPass=trim($_POST["pass"])) $error[]=\'Не заполнено поле "Пароль"\';
получается гораздо читабельнее и элегантнее.
Далее.
session_start(); имеет смысл делать только в случае удачной авторизации. Какой смысл стартовать сессию хакеру, к примеру, подбирающему проль?
$_SESSION[\'username\'] = "";
$_SESSION[\'userpass\'] = "";
это лишнее.
$_SESSION[\'userpass\'] = $userPass;
А это - тем более!
-
самое обидное, что учишь вас, учишь.
пишнешь километры текста. и в фак.
и каждому персонально.
А толку - ноль.
Или "я знаю твое мнение, но сделаю по-своему" или вообще "чего со своими замечаниями лезешь".
Тут еще один кадр был.
Задает идиотский вопрос, типа, "как получить 2х2=5" и в ответ на замечание выдающий сакраментальное "не знаешь, как сделать - молчи лучше!".
Эх. Прав Ксандер. Вырождаются форумы...
-
RomikChef
Ты уж извини, был не прав.
Я не буду оправдываться, но скажу, что так как я новичек в этом деле, то естественно у меня возникают вопросы и проблемы. Если возникла проблема, то я сам пытаюсь сначала ее решить, благо инфо в инете полно. Но если я промаялся 2-3 дня и ничего, тогда я прихожу сюды и спрашиваю идиотские вопросы. Ну а так как ты являешься активным участником данного форума, то ты мне почти постоянно и отвечаешь. Оперативно, конечно, но обычно твои ответы сводились вот к этому:
Восхитительный пассаж.
Сообщения об ошибках - ЕДИНСТВЕННЫЙ способ для программиста узнать, что он написал кривую программу.
Однако вместо того, чтобы переписать ее, мы просто заткнем ей рот.
прелестно.
Сами же растим грабли. на которые потом со всей дури...
видимо, нет спеца по этой проблеме.
Лично у меня апач никогда не зависал.
если имеется в виду спец по поиску на bugs.php.net то не вижу причины, по которой я это должен делать вместо тебя.
Главное, что ты должен понять из этих "шуток" - что ты сильно ошибся форумом.
Да, признаю, был глуп и наивен, но все меняется и не стоит на месте...
-
А теперь вернемся к моим баранам, если вы не против...
Вот такой код у меня получился после всех изменений.
auth.php
$users["demo"]=md5("demo");
$error = array(); // Типа так надо :)
if (isset($_POST["logon"])){
if (!$userName=trim($_POST["user"])) $error[]=\'Не заполнено поле "Имя"\';
if (!$userPass=trim($_POST["pass"])) $error[]=\'Не заполнено поле "Пароль"\';
if (isset($username, $users) && $users[$userName]!=md5($userPass)) { $error[]="Неверный пароль"; }
if (!count($error)) {
session_start();
$_SESSION[\'username\'] = $userName; // С переменными сесси гораздо удобней работать как с суперглобальным массивом.
}
}
if (count($error)){ // Если $error не пуст покажем его содержимое.
echo "Ошибка";
foreach ($error as $value) { echo "- $value
"; }
}
if (!$_SESSION[\'username\']){
?>
exit; // Вывести форму и закончить выполнение скрипта.
}
?>
test.php
require("auth.php");
?>
А вот тут уже что угодно :)
Теперь еще вопросы. мы использовали функцию exit; это означает конец выполнения скрипта и выдачи страницы пользователю. Что тогда происходит с дизайном сайта, если пропадают все закрывающие теги?
-
я написал, как сделать, чтобы проблемы такой не было :-)
-
Neter
воздержись от написания сообщений в этот форум.
-
RomikChef Извини, не знал, что твой идиотизм хронический.
-
А что здесь происходит?
Почему удаляются посты?
И что с моим вопросом?
-
происходит совершенно обычное общение на форуме.
Посты удаляются за глупость.
на твой вопрос я тебе ответил. здесь и в привате.
еще вопросы?
-
Подскажите, нужна ли регистрация переменной:
session_start();
session_register(\'username\');
$_SESSION[\'username\'] = $userName;
или можно обойтись без нее, т.е. так
session_start();
$_SESSION[\'username\'] = $userName;
-
Terion
Не нужна.
[m] Тему 2004 года прикрою на правах историчности.