Forum Webscript.Ru

Программирование => PHP => Тема начата: Rodent от 12 Марта 2004, 00:02:31

Название: Авторизация
Отправлено: 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):
    ?>
    " method="post">

    Username:

    Password:



    elseif ($enter==1):
       echo "Вошли !!!";
    endif;
    ?>

    ну а дальше во все файлы где требуется авторизация я require данный файл. При этом содержимое файлов примерно такое:

    $enter=0;
    require ("admin.php");
    if ($enter==1):
     // а тут уже все что угодно
    endif;
    ?>

    Вот вроде все...
    С уважением, Николай
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 01:04:46
    Народ я тут инфу накопал по своему вопросу и сейчас в ней разбераюсь, но все равно оцените (на плюсы и минусы) данный код, и как его сделать более правильным без использования БД но с использованием и куки и сессии.

    - 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)
    Название: Авторизация
    Отправлено: Макс от 12 Марта 2004, 01:24:54
    Цитировать
    Rodent:
    но все равно оцените (на плюсы и минусы) данный код

    если пхп работает с register_globals = On то взломать можно (вроде).
    Например замени свою форму на такую:
    " method="post">

    Username:

    Password:




    и введи в поля логин/пароль - new_user/1
    c4ca4238a0b923820dcc509a6f75849b - это md5("1");
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 13:50:01
    Так мой сервак, просто так переменные из формы брать не будет их надо сначала объявить типа
    $users[]=$_POST["users"];
    и тому подобное...
    Хотя я могу и заблуждаться...
    Название: Авторизация
    Отправлено: Neter от 12 Марта 2004, 14:23:18
    Цитировать
    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))
    Название: Авторизация
    Отправлено: Макс от 12 Марта 2004, 16:15:08
    Цитировать
    Rodent:
    Так мой сервак, просто так переменные из формы брать не будет их надо сначала объявить типа

     я же написал, что эта дыра только при register_globals = on
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 16:31:19
    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. опять не понял в чем моя ошибка?
    Название: Авторизация
    Отправлено: Neter от 12 Марта 2004, 17:32:17
    Rodent Переменные "глобализируют" только внутри функций, какая версия РНР?.

    2.
    Либо ты пишешь так if (expr){  }
    Либо if (expr):
    endif;

    3. Добавь в начало $error = array();
    И проверяй как if (count($array))

    Почему? Потому что так - правильно.

    [OFF]Люди зацените часть сырца РНРшного сайта http://www.php.net/include/site.inc[/OFF]
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 18:06:36
    Neter
    1. Apache 1.3.26 PHP 4.3.3
    2. C этим тоже разобрался, спасибо что уточнил
    3. Ну добавлю я $error=array();
    Проверю if (count($array)), но чо мне это даст? каков будет ответ?
    что вообще эта за структура count ($array) и что она мне дает?
    Название: Авторизация
    Отправлено: Neter от 12 Марта 2004, 18:13:04
    Rodent Тьфу ты, не $array а $error, count($error) возвратит количество элементов массива, так правильней чем сначала искать есть ли эта переменная а потом сравнивать массив со строкой.
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 18:17:23
    Neter
    То есть если count($error) мне выдает 0, то можно продолжать работать?

    Всем
    Ладно я не много отвлекся от темы. может кто-нить еще даст советы по оптимизации данного вида авторизации. Или то что есть нормально?
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 20:43:53
    Я под конец совсем запулся с сессиями.
    как я понял, для того чтобы зарегистрировать переменную нужно написать
    session_start();
    session_register("user");
    После этого данная переменная появляется в в сессии, но она пока без значения, теперь мы ей присваиваем значение
    $user="admin";
    по идее в сессии теперь находиться переменная user со значением admin. правильно???
    Теперь. как мне добыть данную переменную на других страницах сайта???
    Опять открыть сессию и зарегить переменную
    session_start();
    session_register("user");
    теперь, по идее опять же, если написать
    echo $user;
    мне браузер должен вывести admin.
    Я прав или нет??? сама схема работы сессии мной понята правильно???
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 20:48:46
    И еще мне не совсем нравиться моя авторизация на других страницах сайта

    $enter=0;
    require ("admin.php");
    if ($enter==1):
    // а тут уже все что угодно
    endif;
    ?>

    Ситуация такая. что я допустим нормально зарегился на страничке авторизаторе, перехожу на другие защищенный странички где вставлена ссылка
    reqiure (auth.php);
    и допустим что авторизация не прошла. Тогда скрипт должен тут же прекратить долнейший вывод странички и перенаправить пользователя еще раз зарегиться.
    Название: Авторизация
    Отправлено: Rodent от 12 Марта 2004, 20:50:57
    Я не слишком много вопросов задаю???
    я новичок в пхп, но я стараюсь, перед тем как задавать вопросы проникнуться данной проблемой.
    Ну а в общем данный форум, мне кажется, для того и существует чтобы помогать таким как мне и делиться опытом.
    Или я опять же не прав???
    Название: Авторизация
    Отправлено: Neter от 12 Марта 2004, 21:56:39
    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\']){
    ?>
    " method="post">

    Username:

    Password:



    exit; // Вывести форму и закончить выполнение скрипта.
    }
    ?>

    test.php
    require("auth.php");
    ?>
    А вот тут уже что угодно :)
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 13 Марта 2004, 00:49:49
    Цитировать
    @ Нужна для подавления ошибок

    Восхитительный пассаж.
    Сообщения об ошибках - ЕДИНСТВЕННЫЙ способ для программиста узнать, что он написал кривую программу.
    Однако вместо того, чтобы переписать ее, мы просто заткнем ей рот.
    прелестно.
    Сами же растим грабли. на которые потом со всей дури...
    Название: Авторизация
    Отправлено: Rodent от 13 Марта 2004, 01:08:01
    Огромное спасибо 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, которая убивает все, но дизайн-то требует законченности.

    Вот такие теперь у меня возникают вопросы.
    Название: Авторизация
    Отправлено: Rodent от 13 Марта 2004, 01:10:01
    RomikChef
    а что ты предлагаешь???
    Название: Авторизация
    Отправлено: Neter от 13 Марта 2004, 10:25:47
    RomikChef Рома, я знаю о твоём мнении насчёт этих собак, я это понимаю, но это тот случай когда подавление сообщения об ошибке оправдано. Насчёт @$users[$userName] - это мне и самому не нравится, просто не подумавши написал, впринципе это правильно и ничего страшного в этом нет, но на всякий случай я поправил код. Или ты где-то ошибку увидел? (вопрос с подковыркой ;) )

    Rodent Дам тебе совет насчёт собак, никогда не используй их для функций и собственных переменных, НИКОГДА!
    Название: Авторизация
    Отправлено: Diesel от 13 Марта 2004, 12:05:45
    Neter
    НЕТ собакам(@)! ДА отключению вывода ошибок в php.ini
    НЕТ двойным кавычкам! ДА одинарным![не актуально]
    НЕТ конструкциям типа $var==""! ДА функциям [p]isset[/p] и [p]empty[/p]
    Название: Авторизация
    Отправлено: Diesel от 13 Марта 2004, 12:10:28
    Rodent создавай новые топики для новых вопросов
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 13 Марта 2004, 13:26:16
    Цитировать
    Neter:
    я знаю о твоём мнении насчёт этих собак

    Ничего ты не знаешь!
    Ни-Че-Го!
    Ты сам-то почитай свои оправдания!
    Вчера я был слишком уставший, чтобы заниматься разжевыванием азов.
    Делаю это сейчас.
    Вот смотри, я тебя, неуча, сейчас буду тыкать носом.
    Наглядно показывать, что имея наглость с малыми знаниями иметь свое собственное мнение, ты сам расставляешь себе грабли.
    Цитировать
    @ Нужна для подавления ошибок . т.е. если человек не жмакнул кнопку

    Твои слова?
    А тебе известно о том, что переменная эта может быть не установлена, при том, что форма отправлена? Если просто нажать на ентер. Вот если бы у тебя не было собаки - ты бы этот момент увидел СРАЗУ! По нотайсу. Пришел бы на форум - а как это так - форма отправлена, а переменной нету. И тебе бы объяснили.
    А собакой ты нотайс подавил. В переменных своих ты уверен. И ловил бы глюк хрен знает сколько времени.
    воспитательная часть закончена. Переходим к практической.

    Если надо проверить, есть такая переменная, или нет, то надо использовать функцию isset() и нотайсов не будет, и ясность во всем. Не выполняется условие? Значит, переменная не установлена. Копаем, почему. НО НЕ ЗАТЫКАЕМ ПРОГРАММЕ РОТ!
    И не пишем программ, в которых ошибки являются их частью.
    Хотя, по-моему, некоторые люди просто не в состоянии понять, что сообщения об ошибках сделаны ДЛЯ ПОМОЩИ, а не просто развлечение разработчиков, чтобы досадить несчастным программистам и их надо подавлять.

    Если надо проверить, отправлена была форма, или нет, при условии, что форма одна на странице (что бывает в подавляющем большинстве случаев), достаточно проверить _SERVER[\'REQUEST_METHOD\']. Если форм много и все с одним экшеном, то нужно хидден поле, чтобы их отличить.

    с $_POST["logon"] (вместо которого ты мне подсунул @$users) разобрались.
    Далее.
    @$_POST["user"]
    Как мы уже проверили выше, фолрма пришла постом.
    Значит, поля "юзер" и "пасс" в ней обязательно должны быть.
    А вдруг их нету???
    А если их нету, то это форс-мажорная ситуация! Это или хакер лезет, или ошибка какая-то. Так программисту НАОБОРОТ!!!! НАДО. ОБ. ЭТОМ. ЗНАТЬ!!!
    Что форма передана. а переменные почему-то - нет.
    Ну я совершенно не представляю, как можно быть настолько страусом.
    Ты для заказчика что ли пишешь? Лишь бы скинуть? Ну так отключи сообщения об ошибках ВООБЩЕ ВСЕ. И дело с концом.
    А если ты нормальный программист, если тебя волнует работоспособность программы, то ты должен
    1. написать ее так, чтобы она в штатном режиме никаких ошибок не выдавала. Чтобы ошибки не были ее частью.
    2. ТЩАТЕЛЬНО изучать все сообщения об ошибках, буде таковые появятся. Иисправлять.
    ПРИЧИНУ исправлять, бестолочь! а не сообщение. Болезнь лечить, а не симптом!
    3. Скрывать сообщения об ошибках от юзера - они ему не нужны.
    display_errors=off
    ПОКАЗЫВАТЬ сообщения программисту
    log_errors=on

    Дальше.
    Этот твой  @$users
    Вижу - исправил.
    Опять же - за что ты не любишь примитивную функцию isset?
    она гораздо короче, чем твой аррай кей екзистс и удобнее.
    Тебе кажется, что обе эти функции все равно лишние?
    Ну так учти, что в массиве никто логины с паролями не хранит, и весь этот пример притянут за уши.
    то есть, проверять существование ключа одновременно со сравнением значения  требуется на самом деле достаточно редко.
    В нормальном же применении массивов попытка обратиться к несуществующему индексу - ОШИБКА! Важная ошибка, о которой должен знать программист.
    О которой он будет знать, если не затыкает своей программе рот.
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 13 Марта 2004, 13:37:36
    Rodent
    Я тебе отвечу.
    Однако предупреждаю - если начнутся стоны или обидки, то тема будет немедленно закрыта.
    Я не обсуждаю здесь вопросы твоей гениальности ли убогости. Такое мнение может возникнуть ТОЛКО если
    1. ты считаешь себя гением, а свое решение гениальным
    2. твое рещение критикуется.
    При адекватной же самооценке факт критики воспринимается не как попытка наехать, а как попытка помочь.

    Сейчас ты наткнулся на первые грабли системы "запихнуть весь сайт в один файл". Оставив в стороне эстетическую сторону вопроса, я лишь скажу, что граблей таких будет много.
    К примеру:
    Вот на этом сайте выводится в заголовке окна (в теге title) название темы. А в твоем это сделать затруднительно.

    Заплаток можно будет наставить много. Из-за них твой файл индекс, который не делает НИЧЕГО кроме того, что показывает другие файлы юзеру, будет ВСЕ ВРЕМЯ разрастаться.
    Я считаю, что лучше обойтись без него вовсе. Без лишнего кода, без лишнего файла, без лишнего параметра в адресе.

    Возьми, да раздели свой design.php на две части - верх и низ.
    И подключай в каждом скрипте в нужных местах.
    Таким образом разом снимутся все проблемы. Сохранится легкость смены дизайна. И скрипты приобретут гибкость.
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 13 Марта 2004, 13:46:47
    Цитировать
    $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;

    А это - тем более!
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 13 Марта 2004, 13:50:40
    самое обидное, что учишь вас, учишь.
    пишнешь километры текста. и в фак.
    и каждому персонально.
    А толку - ноль.
    Или "я знаю твое мнение, но сделаю по-своему" или вообще "чего со своими замечаниями лезешь".

    Тут еще один кадр был.
    Задает идиотский вопрос, типа, "как получить 2х2=5" и в ответ на замечание выдающий сакраментальное "не знаешь, как сделать - молчи лучше!".

    Эх. Прав Ксандер. Вырождаются форумы...
    Название: Авторизация
    Отправлено: Rodent от 13 Марта 2004, 14:53:08
    RomikChef
    Ты уж извини, был не прав.
    Я не буду оправдываться, но скажу, что так как я новичек в этом деле, то естественно у меня возникают вопросы и проблемы. Если возникла проблема, то я сам пытаюсь сначала ее решить, благо инфо в инете полно. Но если я промаялся 2-3 дня и ничего, тогда я прихожу сюды и спрашиваю идиотские вопросы. Ну а так как ты являешься активным участником данного форума, то ты мне почти постоянно и отвечаешь. Оперативно, конечно, но обычно твои ответы сводились вот к этому:
    Цитировать
    Восхитительный пассаж.
    Сообщения об ошибках - ЕДИНСТВЕННЫЙ способ для программиста узнать, что он написал кривую программу.
    Однако вместо того, чтобы переписать ее, мы просто заткнем ей рот.
    прелестно.
    Сами же растим грабли. на которые потом со всей дури...

    Цитировать
    видимо, нет спеца по этой проблеме.
    Лично у меня апач никогда не зависал.
    если имеется в виду спец по поиску на bugs.php.net то не вижу причины, по которой я это должен делать вместо тебя.

    Цитировать
    Главное, что ты должен понять из этих "шуток" - что ты сильно ошибся форумом.

    Да, признаю, был глуп и наивен, но все меняется и не стоит на месте...
    Название: Авторизация
    Отправлено: Rodent от 13 Марта 2004, 15:01:30
    А теперь вернемся к моим баранам, если вы не против...
    Вот такой код у меня получился после всех изменений.

    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\']){
    ?>
    " method="post">

    Username:

    Password:



    exit; // Вывести форму и закончить выполнение скрипта.
    }
    ?>


    test.php

    require("auth.php");
    ?>
    А вот тут уже что угодно :)


    Теперь еще вопросы. мы использовали функцию exit; это означает конец выполнения скрипта и выдачи страницы пользователю. Что тогда происходит с дизайном сайта, если пропадают все закрывающие теги?
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 13 Марта 2004, 15:36:03
    я написал, как сделать, чтобы проблемы такой не было :-)
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 14 Марта 2004, 11:43:45
    Neter
    воздержись от написания сообщений в этот форум.
    Название: Авторизация
    Отправлено: Neter от 14 Марта 2004, 13:06:14
    RomikChef Извини, не знал, что твой идиотизм хронический.
    Название: Авторизация
    Отправлено: Rodent от 14 Марта 2004, 21:41:18
    А что здесь происходит?
    Почему удаляются посты?
    И что с моим вопросом?
    Название: Авторизация
    Отправлено: Меняздесьдавнонет от 14 Марта 2004, 22:40:44
    происходит совершенно обычное общение на форуме.
    Посты удаляются за глупость.
    на твой вопрос я тебе ответил. здесь и в привате.
    еще вопросы?
    Название: Авторизация
    Отправлено: Terion от 20 Октября 2006, 05:44:55
    Подскажите, нужна ли регистрация переменной:
            session_start();
            session_register(\'username\');
            $_SESSION[\'username\'] = $userName;

    или можно обойтись без нее, т.е. так
            session_start();
            $_SESSION[\'username\'] = $userName;
    Название: Авторизация
    Отправлено: CGVictor от 20 Октября 2006, 11:02:47
    Terion
    Не нужна.

    [m] Тему 2004 года прикрою на правах историчности.