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

StackOverflow https://stackoverflow.com/questions/77826

  •  09-06-2019
  •  | 
  •  

Вопрос

Одна вещь, которую я в последнее время стал делать чаще, это извлечение некоторых данных в начале выполнения задачи и сохраняем его в $_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;
}
Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

Я постоянно использую переменную session для хранения информации для пользователей.Я не видел никаких проблем с производительностью.Данные сеанса извлекаются на основе файла 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'])."'";

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

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

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

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

Другой способ улучшить проверку входных данных - привести переменную _GET['wave_id']:

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

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

Будет

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

  1. $_SESSION срок действия данных истечет после сессия.gc_maxlifetime секунды бездействия.
  2. Тебе придется не забыть позвонить session_start() для каждого скрипта, который будет использовать данные сеанса.
  3. Масштабирование веб-сайта путем балансировки нагрузки на несколько серверов может стать проблемой, поскольку пользователя нужно будет каждый раз направлять на один и тот же сервер.Решите это с помощью "Липких сеансов".

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

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

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

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

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

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

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

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

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

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

т. е.смотрите пункт "Сообщать без сохранения состояния" в разделе "Краткое введение в REST"...

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

(или любая другая ссылка в википедии на ОТДЫХ)

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top