И снова про авторизацию, а конкретно про сессии

Автор tland, 17 декабря 2010, 17:36:42

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

tland

Уважаемые знатоки SMF!
Ежели что, то сильно не пинайте...

Вот ужо несколько дней перелопачиваю данный форум и другие ресурсы про SMF. Многое ясно кроме одного: каким все таки образом происходит проверка, что пользователь залогинен???
То что из куки берется ID_MEMBER и password, а затем проверяется, ну или логинется с помощью login2() или другой функции, написанной самостоятельно — это понятно.

Не понятно — когда же все же создается сессия, которая потом и проверяется. Ну ведь не может же каждый раз из куки браться пароль и на каждой странице логинеться заново в фоновом режиме? Или так и есть?

Чет запутался совсем. А нужно то всего, чтобы после прохождения авторизации можно было проверить что то из массива $_SESSION, дабы в своем скрипте допустить посетителя к закрома, ну или в личный кабинет, кому как.

Подскажите хде посмотреть. SSI и API смотрел я уже не раз, мож чего пропустил, но как то сессиями там не пахнет.

Drakonsa


tland

Спасибо за предсказуемый ответ, хотя лишний раз носом ткнуть не повредило!

Тем не менее ответа я так и не получил на свой вопрос.

Ниже привожу исследования кода. Версия SMF 1.1.12



В файле index.template.php проверка залогинен ли пользователь происходит через проверку переменной $context['user']['is_logged']
примерно следующим образом:
if($context['user']['is_logged'])
echo '
<td class="titlebg2" height="32">
<span style="font-size: 130%;"> ', $txt['hello_member_ndt'], ' <b>', $context['user']['name'] , '</b></span>
</td>';


Напрашивается вывод: нужно исследовать присвоение значения этой переменной ($context['user']['is_logged'])


Итак, значение переменной $context['user']['is_logged'] определяется в функции loadTheme() (файл Load.php) из булева значения проверки переменной $user_info['is_guest'] (!$user_info['is_guest'])

Значение переменной $user_info['is_guest'] присваивается в функции loadUserSettings() (файл Load.php) причем значение это - результат сравнения $ID_MEMBER с нулем ($ID_MEMBER == 0).
Значение $ID_MEMBER вычисляется путем нескольких проверок самого $ID_MEMBER, взятого из куки, затем из массива $user_settings, который формируется из результата запроса к базе все по тому же $ID_MEMBER, взятого из куки. Затем проверка хэша пароля и куки с хэшем, сформированным из значения переменной $user_settings['passwd']

$check = sha1($user_settings['passwd'] . $user_settings['passwordSalt']) == $password;

Очередная проверка 

$ID_MEMBER = $check && ($user_settings['is_activated'] == 1 || $user_settings['is_activated'] == 11) ? $user_settings['ID_MEMBER'] : 0;

и вот он, сформированный $ID_MEMBER, по результатам проверки которого и формируется значение $user_info['is_guest'] из которого и получается $context['user']['is_logged'].
Но.

Но все вышеописанное справедливо для проверки содержимого куки или же вводимого через форму (пара логин+пароль). А где же запись в сессию? Где я что пропустил?  wallbash

P.S.
Использовать для проверки SSI.php не приемлемо как минимум по этой причине:
require_once($sourcedir . '/QueryString.php');
require_once($sourcedir . '/Subs.php');
require_once($sourcedir . '/Errors.php');
require_once($sourcedir . '/Load.php');
require_once($sourcedir . '/Security.php');

 

tland

Еще немного потестировав работу механизма авторизации все же пришел к выводу, что проверка данных пользователя на соответствие данных в базе проводится каждый раз при загрузке страницы.

После первого входа (через форму, либо через куку из броузера) создается копия данных куки в массиве $_SESSION, а именно $_SESSION['login_'.$cookiename] и если потом принудительно в броузере куку удалить, то сеанс работы с пользователем не разрывается. А вот если после этого очистить содержимое $_SESSION['login_'.$cookiename], то сеанс тут же будет разорван. Впрочем, если очистить $_SESSION['login_'.$cookiename], но оставить при этом куку, то сеанс также не разрывается, но если затем куку удалить — сеанс порвется.

Отсюда и вывод, что сеанс (не сессия) длится пока существует хотя бы одна из этих двух переменных: $_COOKIE[$cookiename] и $_SESSION['login_'.$cookiename].

Теперь для меня остался не понятен вопрос: зачем нужен $_SESSION['rand_code']? Может подскажет кто?

Свои тесты проводил с помощью скрипта logintest.php, помещенного в корень форума. Если кому интересно, прилагаю код:


<?php
function logintest(){
require_once(dirname(__FILE__) . '/SSI.php');
if(!empty($_REQUEST['clear'])){
$_SESSION['login_'.$cookiename] = '';
header("Location: {$boardurl}/logintest.php");
}
echo "Вы вошли как <b>".$context['user']['username']."</b><br /><br />";
ssi_login($boardurl.'/logintest.php');
echo "<br /><br />";
ssi_logout($boardurl.'/logintest.php');
echo "<br /><br />";
echo "<form><input type=checkbox name=clear value=1> - очистить \$_SESSION['login_'.\$cookiename]<br /><input type=submit value=submit></form><br /><br />";
if (isset($_COOKIE[$cookiename]) && preg_match('~^a:[34]:\{i:0;(i:\d{1,6}|s:[1-8]:"\d{1,8}");i:1;s:(0|40):"([a-fA-F0-9]{40})?";i:2;[id]:\d{1,14};(i:3;i:\d;)?\}$~'$_COOKIE[$cookiename]) === 1)
list ($member_id$passhash$timeout) = @unserialize($_COOKIE[$cookiename]);

echo "\$_COOKIE[\$cookiename] section<br />------------<br />\$member_id = "$member_id"<br /><br />\$passhash = "$passhash"<br /><br />\$timeout = "$timeout"<br /><br /><br />";

if (isset($_SESSION['login_'.$cookiename]) && preg_match('~^a:[34]:\{i:0;(i:\d{1,6}|s:[1-8]:"\d{1,8}");i:1;s:(0|40):"([a-fA-F0-9]{40})?";i:2;[id]:\d{1,14};(i:3;i:\d;)?\}$~'$_SESSION['login_'.$cookiename]) === 1)
list ($sess_member_id$sess_passhash$sess_timeout) = @unserialize($_SESSION['login_'.$cookiename]);

echo "\$_SESSION['login_'.\$cookiename] section<br />------------<br />\$sess_member_id = "$sess_member_id"<br /><br />\$sess_passhash = "$sess_passhash"<br /><br />\$sess_timeout = "$sess_timeout"<br /><br /><br />";



echo "<span style=\"font-size:20px\">Массив <b>\$modSettings</b></span><br />";
var_dump($modSettings);
echo "<br /><br />";
echo "<span style=\"font-size:20px\">Массив <b>\$context</b></span><br />";
var_dump($context);
echo "<br /><br />Имя сессии: <b>".session_name()."</b><br /><br />
ID сессии: <b>"
.session_id()."</b><br /><br />
<span style=\"font-size:20px\">Массив <b>\$_SESSION</b></span><br />"
;
var_dump($_SESSION);
}
logintest();

?>