Следует ли избегать переменных сеанса?

36

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

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

Вот некоторые причины, по которым мой коллега не использует их:

  • Нетипизированная природа переменных сеанса
  • Тайм-ауты сеанса, приводящие к потере состояния
  • Глобальная область действия переменных сеанса
  • Серверы балансировки нагрузки теряют сеансы (.Net специфичны?)
  • Перезапуск пулов / серверов приложений
  • Они не нужны
Tjaart
источник
3
using things like query string parameters instead- В этом случае всегда всегда используйте параметры строки запроса, если это возможно. Использование сессии для этого типа параметра хрупко и может привести к странным ошибкам, когда у пользователей открыто несколько вкладок.
Изката
2
личная рекомендация - не советуйтесь со своим коллегой, так как он явно не знает, о чем говорит. Тайм-ауты сессии? Разве он не понимает, что продолжительность сеанса контролируется веб-приложением?
GrandmasterB
2
@GrandmasterB Гм. Либо не знает, что они делают, либо сгорел каждым из этих пунктов в течение своей карьеры (я сам набрал около 4 из них) и знает более подходящие способы борьбы с временным состоянием.
Эд Джеймс
Может кто-нибудь объяснить, пожалуйста, связь между состоянием сеанса и наличием нескольких открытых вкладок? Когда вы открываете новую вкладку, она содержит или теперь содержит состояние предыдущей вкладки? Спасибо.
Рэй

Ответы:

41

Если в вашем приложении есть переменная сеанса, задайте себе вопрос:

Когда я нажимаю кнопку «Назад» в своем браузере, какое значение я хочу получить для моей переменной?

Если ответ «текущее значение», переменные сеанса могут быть полезны. В качестве примера можно привести корзину покупок: вы не ожидаете, что что-то будет удалено из корзины покупок, когда вы вернетесь к истории. Это всегда в своем текущем состоянии.

Если ответ «предыдущее значение», вы не должны использовать переменные сеанса. Плохое использование, которое я видел, включает передачу параметра между страницами. Если я нажимаю кнопку «Назад», чтобы вернуться на страницу, страница не обязательно получает правильный параметр. Кроме того, если я открою две вкладки, как будет вести себя мой сайт?

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

Тим
источник
Я согласен. Когда вы думаете о желаемой семантике с несколькими вкладками, обычно становится очевидным, являются ли переменные сеанса или параметры запроса правильным выбором.
CodesInChaos
Я видел именно эти типы ошибок с переменными сеанса, и по общему признанию изучил трудный путь самостоятельно.
Tjaart
Когда пользователь нажимает кнопку «Назад», ожидают ли они, что товары останутся в корзине до истечения срока их сессии, или они хотят, чтобы товары оставались до тех пор, пока они не будут удалены? Использование какого-либо другого механизма сохранения (например, базы данных) позволит сохранить постоянство за пределами одного сеанса, и кнопка «Назад» будет функционировать так, как ожидал пользователь.
Lawtonfogle
25

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

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

Следующие вопросы зависят от реализации:

Нетипизированная природа переменных сеанса

Глобальная область действия переменных сеанса

Серверы балансировки нагрузки теряют сеансы

Перезапуск пулов / серверов приложений

Например, я чаще всего работаю в PHP и храню информацию о сеансе в реляционной базе данных. Так что мои переменные сеанса набраны. Балансировка нагрузки и перезапуск сервера не вызывают проблем сессий.

Этот более интересный:

Тайм-ауты сеанса, приводящие к потере состояния

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

Давайте не будем отбрасывать всю концепцию сессий только потому, что нам не нравится конкретная реализация. Любая хорошая платформа веб-приложений будет способствовать правильному использованию сеансов для сохранения пользовательских логинов или сохранения чего-либо другого, специфичного для текущего посещения пользователя. Запись базы данных пользователя может (и должна) использоваться для хранения специфических для них вещей при входе в систему. Однако анонимные посетители могут иметь временную информацию, которую также стоит сохранить в своем сеансе, такую ​​как короткий список последних посещенных страниц или предпочтение скрыть уведомление, которое они уже видели. Обычно для хранения сеанса подходит только небольшая временная информация.

Мэтт С
источник
Если честно, у меня был ограниченный опыт работы с фреймворками, кроме .Net. .Net перестает устанавливать значение времени ожидания для ваших сессий. Переменные сеанса также всплывают в коде на стороне сервера в виде нетипизированного словаря. Я обычно оборачиваю этот словарь в правильно типизированные классы, так что я не вижу в этом и проблемы. Вы упомянули, что храните информацию о сеансе в базе данных. В ASP .Net хранилище обрабатывается иначе, либо в клиенте .Net, в базе данных (автоматически управляемой) или в отдельной службе Windows.
Tjaart
Можете ли вы привести примеры предполагаемых целей для сессий?
Tjaart
@Tjaart: я немного расширил последний абзац. Надеюсь, это поможет.
Мэтт С
14

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

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

  • Фиксация сеанса : мощная атака, которая немного легче, если вы можете просто заставить пользователя щелкнуть ссылку, на которой уже есть необходимая информация в URL (вместо того, чтобы пытаться заставить пользователя использовать компьютер, на котором соответственно установлены куки).
  • SQL-инъекция (или другой злонамеренный ввод) : никогда не доверяйте тому, что исходит от пользователя. Переменные сеанса имеют то преимущество, что никогда не покидают сервер, поэтому пользователь не может их напрямую изменять. Несмотря на то, что вы должны очистить данные перед тем, как поместить их в сеанс, вы всегда можете доверять значениям, которые вы получаете впоследствии. Если все передается через строку запроса, у вас есть МНОГО проверки, которую необходимо выполнить, чтобы убедиться, что вы не принимаете злонамеренный ввод.
  • Коррупция данных с использованием фальсифицированных входных данных . Как и при внедрении SQL, сколько данных вы передаете взад и вперед? Насколько это важно? Могу ли я изменить поведение вашего приложения, изменив значение в строке запроса? Могу ли я повредить данные на вашем сервере, изменив значения? Если мне удастся испортить данные на сервере, это повлияет на других пользователей? (Если ваш ответ был «нет», мой ответ «вы уверены? У вас есть много мест, которые вы должны проверить.»).

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

riwalk
источник
2

Переменные сессии в некоторой степени похожи на старые глобальные переменные Basic. Пользователь обязан следить за ними, что в них, их сфере применения и как они используются; как в старых версиях бейсика. При этом зачем кому-то полностью отказываться от использования механизма, который, очевидно, предназначен для того, чтобы стать неотъемлемой и очень важной частью модели программирования (ASP, MVC и т. Д.)?

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

Разве это не то, что мы делаем, когда программируем?

макинтош
источник
1

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

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

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

primehunter326
источник
2
Как получить семантику с несколькими вкладками при использовании сеансов для состояния, участвующего в потоке управления? Сессии хорошо работают для входа в систему и настроек, таких как свойства, но у них нет правильной семантики для большинства других применений.
CodesInChaos
Я не уверен, что то, что я опубликовал, было основано на моем собственном общеизвестном ограниченном опыте создания веб-приложения на основе базы данных в PHP / MySQL. Как обычно обрабатываются несколько вкладок в браузерах (я полагаю, это то, что вы имеете в виду)?
primehunter326
@ primehunter326 С параметрами маршрута или строками запроса или скрытыми полями формы.
Кейси
0

Как уже говорилось ранее, HTTP - это Stateless, а Session Variable нарушает это. Разработка HTTP без сохранения состояния помогает кэшированию ресурсов. Для ресурсов, которые являются общедоступными.

Можно создать сайт без переменной сеанса, но это сложнее. Самым сложным (IMHO) является причудливый вход / выход из системы, схемы аутентификации HTTP не предоставляют инструментов, необходимых для аутентификации через HTML-форму (вы можете взломать что-нибудь с помощью javascript - XHR для https: // untel: passowrd@mydomain.com ) и Еще сложнее выйти из системы и быть совместимым с различными браузерами. было некоторое обсуждение списков рассылки w3 по этому поводу, но если я правильно помню, идея была отброшена.

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

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

Матье
источник