PHP: $_SESSION — Каковы плюсы и минусы хранения временно используемых данных в переменной $_SESSION

В последнее время я стал чаще делать извлечение некоторых данных в начале задачи и сохранение их в $_SESSION['myDataForTheTask'].

Теперь это кажется очень удобным, но я ничего не знаю о производительности, рисках безопасности или подобном, используя этот подход. Это то, что регулярно делают программисты с большим опытом, или это больше любительское занятие?

Например:

if (!isset($_SESSION['dataentry']))
{
    $query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=" . mysql_real_escape_string($_GET['wave_id']);
    $result_taskinfo = $db->query($query_taskinfo);
    $row_taskinfo = $result_taskinfo->fetch_row();

        $dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());

        $_SESSION['dataentry'] = $dataentry;
}

person Community    schedule 16.09.2008    source источник
comment
Ваш SQL-запрос уязвим для атак SQL-инъекций. Например, кто-то может ввести '?wave_id=wave_id', и запрос выберет все строки. (С запросами DELETE, INSERT и UPDATE дело обстоит хуже.) В этом случае вы должны написать код, чтобы убедиться, что это число, и самый простой способ сделать это — intval()   -  person Paige Ruten    schedule 17.09.2008


Ответы (15)


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

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

Я не могу придумать другого способа безопасного хранения временных переменных (поскольку файлы cookie можно легко изменить, и в большинстве случаев это нежелательно), поэтому $_SESSION будет подходящим способом 

person Community    schedule 16.09.2008
comment
они достаточно безопасны, это верно только в том случае, если это выделенный сервер. на виртуальном хостинге другие пользователи на той же машине могут получить доступ к данным php-сессии. - person Jacco; 20.04.2009
comment
Нет, если вы решите хранить данные сеанса в каком-либо месте, отличном от места по умолчанию. Или когда вы используете другой механизм хранения сеансов, например DB или (ваш собственный) memcache. - person Anti Veeranna; 12.07.2009

Механизм $_SESSION использует файлы cookie.

В случае Firefox (и, возможно, нового IE, я сам не проверял) это означает, что сеанс разделяется между открытыми вкладками. Это не то, чего вы ожидаете по умолчанию. И это означает, что сеанс больше не является «чем-то специфичным для одного окна/пользователя».

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

Это очень неудобно, особенно если вы пишете почтовый клиент или что-то еще (например, интернет-магазин). В этом случае вам придется управлять сессиями вручную или вводить постоянно регенерируемый ключ в URL или делать что-то еще.

person Community    schedule 13.10.2008

Я постоянно использую переменную сеанса для хранения информации для пользователей. Я не видел никаких проблем с производительностью. Данные сеанса извлекаются на основе файла cookie (или PHPSESSID, если файлы cookie отключены). Я не вижу в этом большей угрозы безопасности, чем любая другая аутентификация на основе файлов cookie, и, вероятно, более безопасна, чем хранение фактических данных в файлах cookie пользователей.

Просто чтобы вы знали, что у вас есть проблема безопасности с вашим оператором SQL:

SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];

Вам следует НИКОГДА, НИКОГДА НЕ ПОВТОРЯТЬ, брать данные, предоставленные пользователем, и использовать их для выполнения оператора SQL без предварительной очистки. Я бы заключил его в кавычки и добавил функцию mysql_real_escape_string(). Это защитит вас от большинства атак. Таким образом, ваша строка будет выглядеть так:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";
person Community    schedule 16.09.2008

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

Я считаю плохой практикой хранить общие данные в сеансе пользователя. Есть лучшие места для хранения данных, к которым часто будут обращаться несколько пользователей, и, сохраняя эти данные в сеансе, вы будете дублировать данные для каждого пользователя, которому эти данные нужны. В вашем примере вы можете настроить другой тип механизма хранения для данных этой волны (на основе wave_id), который НЕ привязан конкретно к сеансу пользователя. Таким образом, вы извлечете данные один раз, и они сохранят их где-нибудь, чтобы несколько пользователей могли получить доступ к данным, не требуя повторного извлечения.

person Community    schedule 16.09.2008

Если вы работаете на собственном сервере или в среде, где никто не может отслеживать ваши файлы/память на сервере, данные сеанса находятся в безопасности. Они хранятся на сервере, а клиенту отправляется только идентификационный файл cookie. Проблема, конечно, в том, что другие люди могут украсть куки и выдать себя за кого-то другого. Использование HTTPS и отсутствие указания идентификатора сеанса в URL-адресах должны защитить ваших пользователей от большинства этих проблем. (Если вы не будете осторожны, XSS все еще может использоваться для захвата файлов cookie, см. сообщение Джефа Этвуда. на этом тоже.)

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

person Community    schedule 16.09.2008

Еще один способ улучшить проверку ввода — это привести переменную _GET['wave_id']:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";

Я предполагаю, что wave_id является целым числом и что есть только один ответ.

Буду

person Community    schedule 16.09.2008

Несколько других недостатков использования сессий:

  1. Срок действия $_SESSION данных истекает через session.gc_maxlifetime секунд бездействия.
  2. Вам нужно будет не забыть вызвать session_start() для каждого скрипта, который будет использовать данные сеанса.
  3. Масштабирование веб-сайта за счет балансировки нагрузки на нескольких серверах может быть проблемой, поскольку пользователь должен каждый раз направляться на один и тот же сервер. Решите это с помощью «Sticky Sessions».
person Community    schedule 20.04.2009

Элементы $_SESSION хранятся в сеансе, который по умолчанию хранится на диске. Нет необходимости создавать свой собственный массив и помещать его в запись массива «dataentry», как вы это делали. Вы можете просто использовать $_SESSION['pcode'], $_SESSION['modules'] и так далее.

Как я уже сказал, сеанс хранится на диске, а указатель на сеанс хранится в файле cookie. Таким образом, пользователь не может легко получить данные сеанса.

person Community    schedule 16.09.2008
comment
Просто используйте многомерный массив $_SESSION['mystuff']['mydata'] = 'blah'; - person conmulligan; 17.09.2008
comment
@conmulligan: Конечно, но в сеансе не будет ничего, кроме того, что вы туда поместили. Возможно, вы путаете $_SESSION с $_SERVER. - person nsayer; 18.09.2008

ИМО, вполне приемлемо хранить вещи в сеансе. Это отличный способ сделать данные постоянными. Кроме того, во многих случаях это более безопасно, чем хранить все в файлах cookie. Вот несколько опасений:

  • Кто-то может перехватить сеанс, поэтому, если вы собираетесь использовать его для отслеживания авторизации пользователя, будьте осторожны. Прочитайте это для получения дополнительной информации.
  • Это может быть очень ленивый способ хранения данных. Не бросайте все подряд в сеанс, чтобы потом не запрашивать его.
  • Если вы собираетесь хранить объекты в сеансе, либо их файлы классов должны быть включены до запуска сеанса по следующему запросу, либо вам необходимо настроить автозагрузчик.
person Community    schedule 16.09.2008

Zend Framework имеет полезную библиотеку для управления данными сеанса, которая помогает с истечением срока действия и безопасностью (для таких вещей, как капчи). У них также есть полезное объяснение сессий. См. http://framework.zend.com/manual/en/zend.session.html

person Community    schedule 16.09.2008

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

1) Этот PHP может хранить ваши сеансы в папке tmp или другом каталоге, который может быть доступен другим пользователям на вашем сервере. Вы можете изменить каталог, в котором хранятся сеансы, перейдя в файл php.ini.

2) Если вы настраиваете систему с высокой стоимостью, которая требует очень строгой защиты, вы можете зашифровать данные перед их отправкой в ​​​​сеанс и расшифровать их, чтобы использовать их. Примечание: это может привести к слишком большим накладным расходам в зависимости от вашего трафика/емкости сервера.

3) я обнаружил, что session_destroy(); не удаляет сеанс сразу, вам все равно придется ждать, пока сборщик мусора PHP очистит сеансы. Вы можете изменить частоту запуска сборщика мусора в файле php.ini. Но это все еще не кажется очень надежным, больше информации http://www.captain.at/howto-php-sessions.php

person Community    schedule 17.09.2008

Возможно, вы захотите подумать, насколько это REST-ful?

т. е. см. параграф «Общение без гражданства» в «Краткое введение в REST"...

«REST предписывает, чтобы состояние было либо преобразовано в состояние ресурса, либо сохранено на клиенте. Другими словами, сервер не должен сохранять какое-либо состояние связи для любого из клиентов, с которыми он общается, кроме одного запроса».

(или любые другие ссылки в Википедии для REST)

Итак, в вашем случае «wave_id» является разумным ресурсом для ПОЛУЧЕНИЯ, но вы действительно хотите сохранить его в СЕССИИ? Конечно, memcached — это ваше решение для кэширования объекта Resource?

person Community    schedule 11.03.2009

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

Как и во всем, просто будьте осторожны, чтобы вы всегда очищали пользовательский ввод, особенно если вы помещаете пользовательский ввод в переменную $_SESSION, а затем используете эту переменную в запросе SQL.

person Community    schedule 16.09.2008

Это довольно распространенная вещь, и сеанс, как правило, будет быстрее, чем непрерывные обращения к базе данных. Они также достаточно безопасны, так как разработчики PHP усердно работали над предотвращением перехвата сеанса.

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

person Community    schedule 16.09.2008

$_SESSION очень полезен с точки зрения безопасности, так как это способ хранения информации на стороне сервера, когда пользователь активно находится на ваших страницах, поэтому его трудно взломать, если только ваш фактический php-файл или сервер не имеют уязвимых мест, которые используются. Одна очень хорошая реализация — это сохранение переменной для подтверждения того, что пользователь вошел в систему, и разрешение выполнения действий только в том случае, если они подтверждены.

person Community    schedule 29.04.2009