[php]Проблемма с $_SESSION
ну во первых, если ты поставишь в первом файле session_register("nonce");
то оно заработает, т.к. тогда ты зарегишь эту переменную в сессию...
Или же во втором файле тебе надо проверять не сессионную переменную, а массив $_POST, т.к. данные из формы ты передаешь постом, а не сессией...
И втретьих, напиши, что ты глобально хотел сделать, может эта проблема решена более простым способом ?
то оно заработает, т.к. тогда ты зарегишь эту переменную в сессию...
Или же во втором файле тебе надо проверять не сессионную переменную, а массив $_POST, т.к. данные из формы ты передаешь постом, а не сессией...
И втретьих, напиши, что ты глобально хотел сделать, может эта проблема решена более простым способом ?
Пытаюсь запустить вот это - аутентификация пользователя.
Проблема - сделать аутентификацию пользователя. Вот предложили эту ссылку, теперь с ней вожусь.
Стоит php 4.3.0 из денвера. Вроде всё должно работать.
Проблема - сделать аутентификацию пользователя. Вот предложили эту ссылку, теперь с ней вожусь.
Стоит php 4.3.0 из денвера. Вроде всё должно работать.
я хз, но у меня этот url не открывается...
может опишеь, что там ?
может опишеь, что там ?
Существенным требованием к средствам авторизации есть гибкость, которая не всегда достигается стандарнтыми методам. Не всегда можно сконфигурировать сервер для защищенного SSL канала, а обычные средства авторизации (HTTP, сессии) не обеспечивают надежной защиты. Данный метод полностью системно независим и использует только PHP на стороне сервера и JavaScript на стороне клиента. Используется только стандартная функция MD5 (32-битное хеширование, RSA Message Digest Algorytm JS имплементацию которой любезно предоставил Генри Торжман.
MD5 JavaScript
Скачайте себе md5.js который делает MD5 хеш из любой строки. Есть несколько версий его имплементции на JavaScript:
http://opensource.polytechnique.org/cvs/diogenes/md5.js?cvsroot=Public#rev1.1
http://pajhome.org.uk/crypt/md5/md5src.html
http://www.myersdaily.org/joseph/javascript/md5.js
http://www.onicos.com/staff/iz/amuse/javascript/expert/md5.txt
Данные имплементации не проверена на совместимость с non-ascii символами. Вероятнее всего кириллица не будет правильно хешироваться. Также скрипт о-очень медленно работает на броузере Opera 6. Также нужно проверять включена ли поддержка javascript вообще (об этом позже).
Суть метода
Идея авторизации лежит в том, что клиент посылает логин и пароль через обычную форму, но в зашифрованном с помощью случайного ключа виде (challenge response). Без случайного ключа хеширование не было бы оправдано, а в нашем случае, если злоумышленник перехватит хеш, он не сможет его использовать, потому что сервер уже не знает того случайного ключа ($nonce который посылался для хеширования. Для того, чтобы из перехваченных данных получить пароль, лучшего метода чем перебор не существует. При соответствуюших требованиях к паролю усилия на расшифрование будут неоправданы.
Хотя метод достаточно защищеныний, его надежность компрометируется самим механизмом сессий, который предусматривает передачу идентификатора сессии в открытом виде (через УРЛ или Куку). К тому же метод нету смысла использовать для защиты самой информации (информация все равно идет открітім каналом а только для ограничения доступа к редактированию динамического контента
Реализация
Для авторизации необходимо создать 2 PHP скрипта. Первый генерирует случайную строку и посылает клиенту вместе с формой логина и пароля. Даная форма обрабатывается JS, который шифрует введенный пароль и отсылает на другой скрипт. Другой скрипт помнит этот ключ, получает зашифрованный пароль и логин, находит в своей базе (в нашем примере MySQL таблица) соответствующий логину пароль (точнее соответствующий ему MD5 хеш). Он той же функцией MD5, хеширует и сверяет с полученной строкой. Если все этапы прошли успешно на клинте открывается идентификатор сесии, который дает ему право работать с защищенными скриптами.
Теперь к тому как это все работает
Файл login.php
<?php
function make_seed {
list($usec, $sec) = explode (' ', microtime;
return (float) $sec + float) $usec * 100000);
}
mt_srand(make_seed;
$nonce=mt_rand(1, 10000000); #генерируем слуайное число
$nonce=md5($nonce); #превращаем это число в случайную строку
$_SESSION['nonce']=$nonce; #запоминаем наш случайный ключ к следуйщей странице
?>
<html>
<head>
<script language="javascript" src=md5.js>
</script>
<script language="javascript">
function doSend{
document.login.password.value=MD5(document.login.pass.value);
document.login.password.value=MD5(document.login.password.value+document.login.nonce.value);
document.login.pass.value=''; // NOT to send password as a plain text
document.login.nonce.value='';// NOT to send random key
}
</script>
</head>
<body>
<form name="login" method="post" action="loginrespond.php" onSubmit="doSend">
<input type="text" name="login" value="<?=@$_COOKIE['lastlogged']?>">
<input type="password" name="pass">
<input type="submit" value="Log in">
<input type="hidden" value="<?=$nonce?>" name="nonce">
<input type="hidden" value="" name="password">
</form>
</body>
</html>
Дальше необходимо обработать результат отсылки формы авторизации:
loginrespond.php
<?php
session_start;
if (!isset($_SESSION['nonce']) || strlen($_SESSION['nonce'])!=32) die('Illegal challenge response. Possible hack');
#--------- Получение пароля из MySQL-----------------
#- Здесь может быть любой способ получения пароля--
$host='localhost'; $user='inet'; $pass='po32jlkdjl3'; $db='baza';
mysql_connect($host, $user, $pass);
mysql_select_db($db);
$sql="SELECT * FROM tblusers WHERE login='".Trim(@$_POST['login']);
$sql.="' AND activate=1 AND MD5(CONCAT(pass, '".$_SESSION['nonce']."'='".$_POST['password']."'";
$result = @mysql_query($sql) or die('Query failure: '.mysql_error;
if (!mysql_num_rows($result {
die('Неправильный логин или пароль');
} else {
$row=mysql_fetch_array($result);
mysql_free_result($result);
if ($row['requireip']) {
$sql='SELECT * FROM tblip WHERE ip='.ip2long($_SERVER['REMOTE_ADDR']);
$result=$mysql_query($sql);
if (!mysql_num_rows($result {
$msg="<span class=hot>".$_SERVER['REMOTE_ADDR'].":</span><br>";
$msg.="Запрещена работа с этого IP";
die($msg);
}
}
if (isset($row['expires'] {
if (strtotime($row['expires'])<time die('Строк действия вашего доступа исчерпан');
}
// присваиваем переменной сессии уровень доступа для данного юзера
$_SESSION['auth']=$row['authlevel'];
$_SESSION['userid']=(int) $row['id'];
$_SESSION['username']=$row['name'];
/* PHPSESSID Anti-spoofing */
$_SESSION['REMOTE_ADDR']=$_SERVER['REMOTE_ADDR'];
$_SESSION['HTTP_X_FORWARDED_FOR']=@$_SERVER['HTTP_X_FORWARDED_FOR'];
$_SESSION['HTTP_USER_AGENT']=$_SERVER['HTTP_USER_AGENT'];
// запоминаем в куку логин пользователя
setcookie("lastlogged", $row['login'],time+3600*24*30);
header("Location: protected.php");
exit;
}
?>
В приведенном скрипте мы кроме простого сверения паролей проделали ряд полезных вещей
Проверка WHERE activate=1 дает возможность временно отключать юзерам доступ (activate=0)
Проверка поля expires (срок, когда доступ истекат). Если поле не NULL, то проверяется наступила ли уже указання дата
Если поле requireip установлено, то выполняется дополнительная привязка юзера к списку IP-адресов (в нашем случае дополнительная MySQL таблица)
Здесь можно задать общий список white list или привязывать конкретных юзеров к конкретным IP (по userid). Используйте эту проверку осторожно, например если вы постоянно работаете из некоторых IP и хотите вообще ограничить заход с других IP даже если пароль был скомпрометир
MD5 JavaScript
Скачайте себе md5.js который делает MD5 хеш из любой строки. Есть несколько версий его имплементции на JavaScript:
http://opensource.polytechnique.org/cvs/diogenes/md5.js?cvsroot=Public#rev1.1
http://pajhome.org.uk/crypt/md5/md5src.html
http://www.myersdaily.org/joseph/javascript/md5.js
http://www.onicos.com/staff/iz/amuse/javascript/expert/md5.txt
Данные имплементации не проверена на совместимость с non-ascii символами. Вероятнее всего кириллица не будет правильно хешироваться. Также скрипт о-очень медленно работает на броузере Opera 6. Также нужно проверять включена ли поддержка javascript вообще (об этом позже).
Суть метода
Идея авторизации лежит в том, что клиент посылает логин и пароль через обычную форму, но в зашифрованном с помощью случайного ключа виде (challenge response). Без случайного ключа хеширование не было бы оправдано, а в нашем случае, если злоумышленник перехватит хеш, он не сможет его использовать, потому что сервер уже не знает того случайного ключа ($nonce который посылался для хеширования. Для того, чтобы из перехваченных данных получить пароль, лучшего метода чем перебор не существует. При соответствуюших требованиях к паролю усилия на расшифрование будут неоправданы.
Хотя метод достаточно защищеныний, его надежность компрометируется самим механизмом сессий, который предусматривает передачу идентификатора сессии в открытом виде (через УРЛ или Куку). К тому же метод нету смысла использовать для защиты самой информации (информация все равно идет открітім каналом а только для ограничения доступа к редактированию динамического контента
Реализация
Для авторизации необходимо создать 2 PHP скрипта. Первый генерирует случайную строку и посылает клиенту вместе с формой логина и пароля. Даная форма обрабатывается JS, который шифрует введенный пароль и отсылает на другой скрипт. Другой скрипт помнит этот ключ, получает зашифрованный пароль и логин, находит в своей базе (в нашем примере MySQL таблица) соответствующий логину пароль (точнее соответствующий ему MD5 хеш). Он той же функцией MD5, хеширует и сверяет с полученной строкой. Если все этапы прошли успешно на клинте открывается идентификатор сесии, который дает ему право работать с защищенными скриптами.
Теперь к тому как это все работает
Файл login.php
<?php
function make_seed {
list($usec, $sec) = explode (' ', microtime;
return (float) $sec + float) $usec * 100000);
}
mt_srand(make_seed;
$nonce=mt_rand(1, 10000000); #генерируем слуайное число
$nonce=md5($nonce); #превращаем это число в случайную строку
$_SESSION['nonce']=$nonce; #запоминаем наш случайный ключ к следуйщей странице
?>
<html>
<head>
<script language="javascript" src=md5.js>
</script>
<script language="javascript">
function doSend{
document.login.password.value=MD5(document.login.pass.value);
document.login.password.value=MD5(document.login.password.value+document.login.nonce.value);
document.login.pass.value=''; // NOT to send password as a plain text
document.login.nonce.value='';// NOT to send random key
}
</script>
</head>
<body>
<form name="login" method="post" action="loginrespond.php" onSubmit="doSend">
<input type="text" name="login" value="<?=@$_COOKIE['lastlogged']?>">
<input type="password" name="pass">
<input type="submit" value="Log in">
<input type="hidden" value="<?=$nonce?>" name="nonce">
<input type="hidden" value="" name="password">
</form>
</body>
</html>
Дальше необходимо обработать результат отсылки формы авторизации:
loginrespond.php
<?php
session_start;
if (!isset($_SESSION['nonce']) || strlen($_SESSION['nonce'])!=32) die('Illegal challenge response. Possible hack');
#--------- Получение пароля из MySQL-----------------
#- Здесь может быть любой способ получения пароля--
$host='localhost'; $user='inet'; $pass='po32jlkdjl3'; $db='baza';
mysql_connect($host, $user, $pass);
mysql_select_db($db);
$sql="SELECT * FROM tblusers WHERE login='".Trim(@$_POST['login']);
$sql.="' AND activate=1 AND MD5(CONCAT(pass, '".$_SESSION['nonce']."'='".$_POST['password']."'";
$result = @mysql_query($sql) or die('Query failure: '.mysql_error;
if (!mysql_num_rows($result {
die('Неправильный логин или пароль');
} else {
$row=mysql_fetch_array($result);
mysql_free_result($result);
if ($row['requireip']) {
$sql='SELECT * FROM tblip WHERE ip='.ip2long($_SERVER['REMOTE_ADDR']);
$result=$mysql_query($sql);
if (!mysql_num_rows($result {
$msg="<span class=hot>".$_SERVER['REMOTE_ADDR'].":</span><br>";
$msg.="Запрещена работа с этого IP";
die($msg);
}
}
if (isset($row['expires'] {
if (strtotime($row['expires'])<time die('Строк действия вашего доступа исчерпан');
}
// присваиваем переменной сессии уровень доступа для данного юзера
$_SESSION['auth']=$row['authlevel'];
$_SESSION['userid']=(int) $row['id'];
$_SESSION['username']=$row['name'];
/* PHPSESSID Anti-spoofing */
$_SESSION['REMOTE_ADDR']=$_SERVER['REMOTE_ADDR'];
$_SESSION['HTTP_X_FORWARDED_FOR']=@$_SERVER['HTTP_X_FORWARDED_FOR'];
$_SESSION['HTTP_USER_AGENT']=$_SERVER['HTTP_USER_AGENT'];
// запоминаем в куку логин пользователя
setcookie("lastlogged", $row['login'],time+3600*24*30);
header("Location: protected.php");
exit;
}
?>
В приведенном скрипте мы кроме простого сверения паролей проделали ряд полезных вещей
Проверка WHERE activate=1 дает возможность временно отключать юзерам доступ (activate=0)
Проверка поля expires (срок, когда доступ истекат). Если поле не NULL, то проверяется наступила ли уже указання дата
Если поле requireip установлено, то выполняется дополнительная привязка юзера к списку IP-адресов (в нашем случае дополнительная MySQL таблица)
Здесь можно задать общий список white list или привязывать конкретных юзеров к конкретным IP (по userid). Используйте эту проверку осторожно, например если вы постоянно работаете из некоторых IP и хотите вообще ограничить заход с других IP даже если пароль был скомпрометир
насколько я понимаю, данная строка
Для начала надо бы запустить сессию, (session_start;)? а уже потом писать в нее переменные...
И лучше ИМХО писать session_register("имя_переменной");
что бы ее зарегистрить...
Попробуй....
$_SESSION['nonce']=$nonce; #запоминаем наш случайный ключ к следуйщей страницеабсолютно ничего не делает...
Для начала надо бы запустить сессию, (session_start;)? а уже потом писать в нее переменные...
И лучше ИМХО писать session_register("имя_переменной");
что бы ее зарегистрить...
Попробуй....
Спасибо, буду пробовать
Не работает.
возможно я в синтаксисе ошибся, но общая тема такая:
открываешь сессию,
регистришь в ней переменную,
задаешь переменной значение,
переходишь на другую страницу,
считываешь значение...
ЗЫ Порядок шагов важен.
+ задавать занчение переменной надо именно в тексте, а не в функции.. локальные переменные не регистрятся.
открываешь сессию,
регистришь в ней переменную,
задаешь переменной значение,
переходишь на другую страницу,
считываешь значение...
ЗЫ Порядок шагов важен.
+ задавать занчение переменной надо именно в тексте, а не в функции.. локальные переменные не регистрятся.
Всё так и делал. Но получилось через $_POST - данные пересылает, пароль проверяет. Только я не понял, зачем нужет 'nonce'.
ну там типа на этом вся секьюрность строилась...
А так - выкидывай код нах и просто пиши форму логин-пароль и проверяй ее после отсылки (без всяких js) и заноси в сессию данные, которые нужны...
А так - выкидывай код нах и просто пиши форму логин-пароль и проверяй ее после отсылки (без всяких js) и заноси в сессию данные, которые нужны...
Лёх, не уверен, но по-моему при работе с $_SESSION не нужно делать session_register почитай php_manual, я на линухе, поэтому пока не могу.
>я на линухе, поэтому пока не могу.
а в чём проблема?
а в чём проблема?
Да, абсолютно верно, session_register остался по-моему с тех времен когда register_globals было on.
Вобще достаточно внести в $_SESSION["переменная"] значение и она зарегится. по крайней мере при дефолтных настройках.
Вобще достаточно внести в $_SESSION["переменная"] значение и она зарегится. по крайней мере при дефолтных настройках.
ну это... я не оспариваю такой вариант... Просто й чела он не пашет... И мой тоже...
И вообще ниче не работает...
чем на меня гнать - помогли бы автору треда..
И вообще ниче не работает...
чем на меня гнать - помогли бы автору треда..
Разобрался с сессиями. Всё работает, пароль хеширует, передаёт, проверяет и тд.
так че там было то ?
Нам тоже интересно...
Нам тоже интересно...
Просто не до конца разобрался. Нужно было каждый раз сессию открывать, а я думал, что раз открыл и всё. Вообщем "проект" я закончил, всем спасибо за помощь
Оставить комментарий
iakobi91
Есть два файла. Превый отсылает данные из формы на второй - log.php.Форма в первом:
Начало обработки файла в log.php:
Прога выдаёт 'Illegal challenge response. Possible hack'.
В чём фишка?
track_vars = On
register_globals = On или Off - нет разницы, не работает.