Войти

Показать полную графическую версию : Авторизация на PHP


Qwe1
24-02-2007, 13:15
Дома установлен Denver, на котором скрипт авторизации работает, и работает отлично; заливаю к хостеру - не работает! Логин и пароль хранятся в файле "passw": на одной строке - одна пара. Вместо функции "strcmp" использовалось обычное сравнение "==" - ничего не изменяется. Переменная "auth", регистрируемая в сессии, нужна для проверки в защищенном файле.
Где искать ошибку?


<?
if(!isset($PHP_AUTH_USER))
{
Header("WWW-Authenticate: Basic realm=\"Private\"");
Header("HTTP/1.0 401 Unauthorized");
echo "<p>Авторизация отменена пользователем!</p>";
exit;
}
else
{
// Сравниваем введенные значения с парой логин-пароль из файла с паролями
session_start();
session_register("auth");
$auth = 0;
foreach(file("passw/passw") as $k)
{
if(strcmp(substr($k,0,-2), "$PHP_AUTH_USER $PHP_AUTH_PW") == 0)
$auth = 1;
}
if($auth != 1)
{
Header("WWW-Authenticate: Basic realm=\"Private\"");
echo "<p>Неверный логин или пароль!</p>";
session_unregister("auth");
}
else // Авторизация прошла успешно
{
Header("Location: edit.php");
}
}
?>

vadimiron
24-02-2007, 13:25
Qwe1
А почему не работает? Какие ошибки выдаются??

Qwe1
24-02-2007, 13:49
Окно с вводом логина и пароля появляется, но обработка и анализ введенных значений и просто нажатий на кнопки не верна:
1) Если ввести правильные Л/П, то они не подходят и опять выдается окно с вводом. Так продолжается 3 раза в IE и бесконечно раз в FF и Opere.
2) Если ввести неправильные Л/П или оставить пустыми - всё тоже самое.
3) Если ввести сначала верные Л/П, нажать ОК (опять появится окно с вводом), потом неверные и нажать ОК - все проходит!
4) Если нажать Отмена, то в IE - "Авторизация отменена пользователем!" - то есть так и должно быть, в FF и Opere - "Неверный логин или пароль!" - непонятно, почему.

Главное, конечно же, это то, что скрипт (или еще что-то) не воспринимает верные логин и пароль с первого раза. Дома же все работает и все браузеры одинаково ведут себя (кроме 3-х раз IE).

vadimiron
24-02-2007, 14:22
foreach(file("passw/passw") as $k)
Вы уверены, что на хочтинге у Вас читается файл?? Может доступ к файлу не установлен, соответственно он не читается и поэтому не могут правильные логин и пароль из файла прочитаться

Qwe1
24-02-2007, 14:31
Да, проверял!
$a=file("passw/passw");
echo $a[0];

Ам может это дело в substr($k,0,-2)? У меня дома Windows, значит 2 символа конца строки, а у хостера Linux - значит 1 символ?

vadimiron
24-02-2007, 14:51
Qwe1Ам может это дело в substr($k,0,-2)? У меня дома Windows, значит 2 символа конца строки, а у хостера Linux - значит 1 символ?
Попробуйте использовать trim()

Qwe1
24-02-2007, 15:45
- Я изменил substr($k,0,-1) - стало работать (у хостера, дома - нет). Смущает только то, что и при 2-х символах тоже работало, хоть и не с первого раза.
- трим проверил - тоже работает. Пожалуй, это "кроссплатформенный" способ - работает и там и там!

Но обнаружил еще один момент: в защищенном файле в самом начале я вставил следующий код:

<?
session_start();
if((session_is_registered("auth") == false) && (@$auth != 1))
{
echo "<a href=\"editnews.php\" target=\"_top\">Необходима авторизация!</a>";
exit;
}
?>

Дальше идет форма и другой HTML-код. Переменная "auth" больше нигде не участвует.

Дома: если ввести адрес этой страницы через браузер, сработает "защита", перенаправляющая на файл с авторизацией (то есть на файл из первого поста). Если зайти через файл авторизации - все ок.
У хостера: через браузер - тоже самое, а вот через страницу авторизации - не совсем. Авторизация проходит, перенаправление на защищенную страницу тоже, но при нажатии на кнопку отправить формы (action которой ведет на эту же (защищенную) страницу!) опять требуется авторизация, то есть код проверки переменной auth уже не проходит (словно мы зашли через браузер). Если ввести Л/П, то все ок. Получается - как бы 2 авторизации!

vadimiron
24-02-2007, 16:12
Qwe1
Попробуйте инклудить код из вашего первого поста в начало каждого защищённого файла - вроде это так делается
То есть без редиректов всяких, просто инклуд.
Тогда и в сессию ничего писать не надо

Qwe1
24-02-2007, 16:44
То есть переменные $PHP_AUTH_USER и $PHP_AUTH_PW хранятся также как и сессионные - до закрытия окна или явного уничтожения?

vadimiron
24-02-2007, 17:30
Qwe1
По идее да, браузер их хранит. Эти заголовки обрабатыват же браузер

Qwe1
24-02-2007, 18:02
При моей авторизации проверка пароля осуществляется один раз, а потом проверяется лишь "флажок" - авторизация пройдена. Если вставлять код из первого поста везде, где надо авторизироваться, то каждый раз будет осуществляться проверка, что связано со считыванием файла и перебором (или выборкой из БД). Если паролей мало, то это еще терпимо, если много - то лишняя трата времени и ресурсов. Но в любом случае, лучше стремиться к оптимальному алгоритму авторизации...

vadimiron
24-02-2007, 18:12
Qwe1
Да, но файл, который должен быть защищён пока только один, а если их много появится?? Тогда будете копировать страницу авторизации для каждого файла?

Qwe1
24-02-2007, 19:41
vadimiron
Зачем? В каждый защищенный файл вставляется проверка "флажка": см. пост 7!

vadimiron
24-02-2007, 20:21
Header("Location: edit.php");
Но из авторизации идёт прямое перенаправление на защищённый файл!!!
как вы переправите на другой защищённый файл?? можно конечно параметрами передовать, но данный метод авторизации используют в основном так как я сказал.

vadimiron
24-02-2007, 20:33
И кстати файл в одном случае называется edit.php, в другом - editnews.php
Ещё раз перепроверьте весь код и в крайнем случае здесь киньте

Qwe1
25-02-2007, 00:27
Да-да, все верно - буду инклюдить! Только не понятно - как без сессий-то обойтись?

Я делаю так: в самое начало файла, который должен быть защищен, вставляю код:

<?
require "auth.inc";
if((session_is_registered("auth") == false) || (@$auth != 1))
{
unset($PHP_AUTH_USER); // не работает
Header("HTTP/1.0 401 Unauthorized"); // вместо этого можно сделать редирект на $_SERVER['HTTP_REFERER']
exit;
}
<...>
?>

Содержимое файла "auth.inc":

<?
if(!isset($PHP_AUTH_USER))
{
Header("WWW-Authenticate: Basic realm=\"Private\"");
Header("HTTP/1.0 401 Unauthorized");
echo "<p>Авторизация отменена пользователем!</p>";
exit;
}
else
{
// Сравниваем введенные значения с парой логин-пароль из файла с паролями
session_start();
session_register("auth");
$auth = 0;
foreach(file("passw/passw") as $k)
{
if(trim($k) == "$PHP_AUTH_USER $PHP_AUTH_PW")
$auth = 1;
}
}
?>


1) Теперь правильно?
2) Хочу сделать так, чтобы после неверного ввода Л/П можно было бы опять вводить Л/П - но unset($PHP_AUTH_USER); не помогает...

vadimiron
25-02-2007, 00:57
Не, проверка $auth в защищённом файле вообще не нужна, всю логику авторизации должен выполнять auth.inc


if(!isset($PHP_AUTH_USER))
// пользователь неизвестен
{
Header("WWW-Authenticate: Basic realm=\"Admin Center\"");
Header("HTTP/1.0 401 Unauthorized");
exit("Вы либо неправильно вводите Ваши имя и пароль, которые задали при регистрации, либо ещё не зарегистрированы.<br>Зарегестрироваться можно прямо <a href='reg_user.php'>здесь</a>");
}
else // пользователь известен, неизвестен пароль
{

$auth=0;
// просмотр файла
foreach(file("passw/passw") as $k)
{
if(trim($k) == "$PHP_AUTH_USER $PHP_AUTH_PW")
{
$auth = 1;
break;
}
}

if ($auth!=1)
{
Header("WWW-Authenticate: Basic realm=\"Admin Center\"");
Header("HTTP/1.0 401 Unauthorized");
exit("Вы либо неправильно вводите Ваши имя и пароль, которые задали при регистрации,
либо ещё не зарегистрированы.<br>Зарегестрироваться можно прямо <a href='reg_user.php'>здесь</a>");

}

}


B всё - сам файл будет исполнятся, если была произведена авторизация, если же, будет срабатывать exit

Qwe1
25-02-2007, 01:46
А, ну да, точно! Спасибо!

Но, все же, постоянная проверка логина и пароля, вместо "флажка", пожалуй, не очень хорошо!?




© OSzone.net 2001-2012