Огромная проблема с авторизацией.

boltikov

Новичок
Огромная проблема с авторизацией.

Есть большой проект знакомств, до 250000 хитов, до 280 пользователей онлайн одновременно. Проект состоит из общей части и закрытой (только для авторизированных пользователей: редактирование анкеты, пользовательская стастистика, адресная книга, переписка). Пользовательские данные храняться в стандартном файле сессии, все в одной переменной $sessvar.

Для проверки авторизован пользователь или нет проверяется $sessvar['user']['auth'] - если она true, то пользователь авторизован. В дальнейшем для авторизованных пользователей все индивидуальные страницы выводятся на основе $sessvar['user']['id'] (уникальный), который представляет себе PRIMARY KEY (auto_incriment) таблицы пользователей.

Примерно три недели назад начались проблемы. Пользователи открыв сайт, то есть набрав в адресной строке браузера адрес сайта или перейдя по ссылке из письма в свой почтовый ящик (ссылка типа http://site/in/inbox/ ) оказываются авторизованы под чужим логином. Соответсвенно они могут менять чужую анкету, вести переписку от имени другого пользователя.

Работа с той частью проекта, которая требует авторизации, без поддержки кукиз невозможна.

Для решения проблемы был пересмотен весь код на предмет не задается ли где-нибудь $sessvar['user']]['id'] случайным образом, а не из сессии или ищ данных пришедших в результате sql-запроса при авторизации. Нет, не задается.

Потом был в ручную задан механизм определения id сессии с проверкой существуют ли такой файл или нет.
PHP:
if (!$_COOKIE["LOVESESS2"]) {
	$sess_id = "";
	do {
		$sess_id = sha1($_SERVER['HTTP_X_FORWARDED_FOR']."#".$_SERVER['REMOTE_ADDR'].microtime().$_SERVER["HTTP_USER_AGENT"]);
		$sess_file = "/tmp/sess_".$sess_id;
	} while (is_file ($sess_file));
	session_id ($sess_id);
}
Не то ни другое не помогло. Также как и запрет кэширования.
PHP:
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");    // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");    // always modified
header("Cache-Control: no-store, no-cache, must-revalidate");  // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");                          // HTTP/1.0
Также был просомтрен баг лист PHP на предмет работы сессиями но ничего аналогичного замечано не было.


В настоящее время проект работает на
FreeBSD ******.ru 4.11-RELEASE FreeBSD 4.11-RELEASE #2: Thu Ja i386
Apache/1.3.33 (Unix)rus/PL30.20 PHP/4.3.10 mod_accel/1.0.31

Месяц назад был совершен перенос проект на данный сервер, до этого он работал на FreeBSD 4.9-p2 Apache/1.3.31 (Unix) mod_accel/1.0.31 php 4.3.9 и вышеописанной проблемы не было.

В чем может быть проблема? Кривость рук и соответсвенно кода? Какой-то баг PHP или PHP и чего-то еще?
 

vitus

мимо проходил
а чем тебя не устроил стандартный механизм сессий?
 

boltikov

Новичок
Автор оригинала: vitus
а чем тебя не устроил стандартный механизм сессий?
Полностью устраивает. Это я уже описывал как я пытался бороться с данной проблемой.
 

AHTIXPICT

Новичок
Может не решит проблему конечно,
Но можно узнать смысл использования такой переменной:
$sessvar['user']['auth']
можно же было просто
$_SESSION['auth']
и если нужно еще user то:
$_SESSION['user']
 

AHTIXPICT

Новичок
Прости что вынес твой ответ из привата, но интресно

-----------------
>Мне удобнее зарегистрировать глобальную перменную для сессии и работать с ней.
>$sessvar['user'] - это массив в котором хранятся данные о пользователе.
------------
А почему бы в сесси не хранить только идентификатор пользователя, который будет говорить о том что пользователь залогинен, а все данные о нем всеравно хранятся я думаю в базе данных, вот и доставай их из базы когда нужно, ведь id уже есть
 

vitus

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

а уникальное имя файла можно получить специальной функцией
string tempnam ( string dir, string prefix)
 

boltikov

Новичок
В сессии и так хранится id пользователя. И страница редактирования анкеты, страница входящих писем выдается именно исходя из его значения.

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

К данной проблеме это не имеет никакого отношения :) поэтому если интересен именно этот вопрос лучше перейти в приват... дабы не засорять топик.

-~{}~ 28.02.05 10:26:

Автор оригинала: vitus
думаю проблема не в этом, а в том что сессионная кука у двух пользователей почему-то оказывается одинаковой, смотри на время жизни кук и сессионных файлов.
Я уже переписал механизм выдачи id сессии. Каким он стал можно посмотреть в первом посте. При этом идет проверка на существует такой файл сессий или нет.

*бьюсь головой об стену* Как могут совпадать кукизы?
 

AHTIXPICT

Новичок
Ладно, моя дальше будет сидеть молча только последнее:

<?php
session_start();
$sesvar['user']['auth'] = true;
$sesvar['user']['name'] = "Gayvoronsky Maksim";
$_SESSION['sesvar']=$sesvar;
//print_r($_SESSION['sesvar']);
?>
в файле сессии записывается такая информация:
sesvar|a:1:{s:4:"user";a:2:{s:4:"auth";b:1;s:4:"name";s:18:"Gayvoronsky Maksim";}}

Мне кажется что при нагрузке в 280 залогиненых онлайн пользователей, лучше было бы использовать ID в сессии и остальное держать в базе.
 

boltikov

Новичок
Во-первых:
session_start();
session_register("sessvar");
так более правильно :)

Во-вторых, как я уже писал, лишний запрос это лишняя нагрузка на базу, и соответственно, замедленее скорости выполнения запросов.
 

AHTIXPICT

Новичок
1,
Кто тебе сказал что так более правильно?
:Идем читать ФАКИ и мануалы

2, А лишнее обращение к файлу и его парсинг - это не нагрузка

-~{}~ 28.02.05 10:37:

у тебяя еще наверное register_globals=On
и это тоже для тебя правильно?
 

vitus

мимо проходил
Я уже переписал механизм выдачи id сессии. Каким он стал можно посмотреть в первом посте. При этом идет проверка на существует такой файл сессий или нет.

*бьюсь головой об стену* Как могут совпадать кукизы?
- ну не помогло ведь :)
- бейся, могут - факт в том что человек со своей кукой таки получает чужой профайл.
 

Gas

может по одной?
boltikov
забудь об этом
PHP:
session_register("sessvar");
и если действительно у тебя register_globals=On, может быть проблемма в этом, но сказать точно что у тебя не так врят-ли кто-то сможет, отлаживай
http://phpclub.ru/talk/showthread.php?postid=412839#post412839

AHTIXPICT
не вижу почему информацию о пользователе не держать в сессии
 

boltikov

Новичок
Автор оригинала: Gas
и если действительно у тебя register_globals=On, может быть проблемма в этом, но сказать точно что у тебя не так врят-ли кто-то сможет, отлаживай
http://phpclub.ru/talk/showthread.php?postid=412839#post412839
Попробую поискать решение в этом направление.

-~{}~ 28.02.05 11:42:

s1.php
PHP:
<?php 
session_start();
session_register("xxx");
$xxx['var'] = 'value2'; 
header('location: /test/s2.php?'.session_name().'='.session_id()); 
?>
s2.php
PHP:
<?php 
session_start();
session_register("xxx"); 
echo $xxx['var'].'<br>'; 
$var = 'new value2'; 
echo $xxx['var']; 
?>
output s2.php
value2
value2

Видно проблема не в этом... но поискать в данном направление еще попробую.
 

Gas

может по одной?
boltikov
Не по теме:
тест-кейсы нужно копировать полностью как они есть, а не придумывать.
Твой код при отключенных глобалсах вообще работать не будет и справедливо скажет "Undefined variable: xxx"
Но это совершенно не объясняет почему у тебя перестало работать.
 

boltikov

Новичок
Gas
Я скопировал. Да, в том виде, как было в топике, работает.

После этого привел тест к тому виду, как у меня в проекте. Не работает. Результат показал.
 

Gas

может по одной?
Не про тест, эта ссылка может помочь найти причину, почему у тебя перестала работать авторизация, равно как может и не помочь. Всё в твоих руках.
 
Сверху