Ведение сессии через строку запроса в PHP

1

php.net говорит:

Поддержка сеанса в PHP заключается в способе сохранения определенных данных в последующих доступах.

Посетителю, обращающемуся к вашему веб-сайту, присваивается уникальный идентификатор, так называемый идентификатор сеанса. Это либо сохраняется в файле cookie на стороне пользователя, либо распространяется в URL-адресе.

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

Воспроизведение моего эксперимента:

У меня есть следующий скрипт, хранящийся в /var/www/html/script.php:

<?php  
  session_start();
  if (isset($_SESSION["accesses"])) ++$_SESSION["accesses"];
  else $_SESSION["accesses"] = 1;
  echo "This page has been accessed ", $_SESSION["accesses"], " times";
?>

С настройками php по умолчанию в php.ini, то есть:

session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0

все работает нормально. То есть, когда я перехожу в localhost/script.php в свой браузер и обновляю страницу несколько раз, счетчик работает так, как полагают.

Когда я отключил куки файлы в моем браузере, счетчик больше не работает, когда я обновляю страницу несколько раз (она остается 1 раз). Затем я читал онлайн, что поддержка php-сессии через строку запроса отключена по умолчанию. Затем я пошел и изменил php.ini следующим образом:

session.use_cookies = 0
session.use_only_cookies = 0
session.use_trans_sid = 1

После перезагрузки apache2 с

service apache2 reload

счетчик в скрипте не работает. Я попробовал несколько комбинаций настроек в php.ini, но не повезло.

Я использую PHP 5.5.9 и Apache 2.4.7.

Вопрос:

Я понимаю, что когда куки отключены и передача идентификатора сеанса через строку запроса включена в php.ini, после первого GET php должен видеть, что в строке запроса не было идентификатора сеанса. Затем php инициализирует идентификатор сеанса для пользователя и отправляет ответ, который перенаправляет клиент на тот же URL с идентификатором сеанса в строке запроса. Все это происходит без написания кода - это делается модулем php для поддержания сеанса.

Это, по крайней мере, то, что я ожидал. Насколько это действительно так? Я предполагаю много о вещах, которые PHP делает автоматически? Но если да, то что это такое: "Это либо хранится в cookie на стороне пользователя, либо распространяется в URL". на php.net? Если _SESSION не работает, когда файлы cookie отключены, не следует ли это просто так сказать?

РЕДАКТИРОВАТЬ:

Дополнительные комментарии для ответа ниже:

Тайна решена. Поддержание сеанса по строке запроса работает так же, как в главном ответе ниже. Чтобы увидеть это в действии, я изменил сценарий в /var/www/html/script.php, чтобы:

<?php  
  session_start();
  if (isset($_SESSION["accesses"])) ++$_SESSION["accesses"];
  else $_SESSION["accesses"] = 1;
  echo "This page has been accessed ", $_SESSION["accesses"], " times";
  echo '<br><a href="script.php">revisit</a>';
?>

Вы можете видеть, что просто обновление страницы обрабатывается PHP как несколько попыток инициализации нового сеанса. Только когда вы нажимаете на ссылку "revisit", идентификатор сеанса фактически внедряется (автоматически с помощью PHP) в ссылку, и счетчик начинает работать (с этого момента он увеличивается, повторяя ссылку или обновляя).

Еще одно слово о настройках в php.ini (Примечание: я сделал все эксперименты ниже в Firefox 39.0. Поведение может отличаться в других браузерах.):

Вариант 1. Если вы хотите, чтобы PHP использовал файлы cookie для поддержки сеанса (если они включены в браузере клиента) и использовать строку запроса (если файлы cookie отключены), убедитесь, что ваш php.ini имеет следующие настройки:

session.use_cookies = 1
session.use_only_cookies = 0
session.use_trans_sid = 1

Первый по умолчанию включен (по крайней мере, в моей версии PHP, см. Выше). Остальные два изменены из значений по умолчанию. Вам нужно изменить их оба.

Очень интересно, как это работает, потому что, когда вы выполняете первый запрос GET, вы не передаете идентификатор сеанса в строке запроса, а cookie не задан, поэтому PHP не знает, следует ли переписывать ссылки (см. (см. ниже) или установите файл cookie (который потенциально может не работать).

Что он делает, он пытается ОБА: вы можете видеть, что при первом доступе ссылка "revisit" в приведенном ниже примере была перезаписана php, чтобы содержать идентификатор сеанса, а также первый ответ сервера пытается установить cookie.

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

Вариант 2. Если вы хотите, чтобы PHP использовал файлы cookie для поддержки сеанса (если они включены в клиентском браузере), но НЕ прибегать к использованию строки запроса, если файлы cookie отключены, придерживайтесь настроек по умолчанию, которые:

session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0

Вариант 3: Если вы хотите, чтобы PHP исключительно использовал строку запроса для поддержки сеанса (который НЕ РЕКОМЕНДУЕТСЯ), даже если куки включены, используйте:

session.use_cookies = 0
session.use_only_cookies = 0
session.use_trans_sid = 1

Обратите внимание, что это полностью противоположно настройкам PHP по умолчанию. Для этого есть веская причина.

  • 0
    Использование session id в querystring может привести к session hijacking .
  • 2
    @ DarkBee Вопрос подтверждает это: «Я делаю это исключительно в образовательных целях. Я знаю, что это не рекомендуется».
Показать ещё 1 комментарий
Теги:
cookies
session

2 ответа

2
Лучший ответ

Я слишком много думаю о том, что PHP делает автоматически?

Да, этой части не бывает:

Затем php отправит ответ, который перенаправляет клиент на тот же URL с идентификатором сеанса в строке запроса.

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

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

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

1

Поскольку идентификатор сеанса в строках запроса абсолютно не рекомендуется, но возможен в PHP 4.2. 0+, большинство хостеров по умолчанию отключили их в конфигурации apache. Просто проверьте конфигурацию apache/vhost/htaccess для этой строки:

php_flag session.use_trans_sid off

Обновление (благодаря IMSoP): Чтобы проверить, отключен ли session.use_trans_sid где-то или нет, вы можете просто добавить phpinfo(); на ваш скрипт и проверьте значение настройки.

Если вы используете версию PHP старше 4.2, вам нужно скомпилировать PHP, используя параметр --enable-trans-sid, см. Руководство по PHP:

Если вы не используете PHP 4.2.0 или новее, вам нужно включить его вручную при создании PHP. В Unix, pass -enable-trans-sid для настройки. http://de2.php.net/manual/en/session.idpassing.php

Если вы это сделали, вы можете включить session.use_trans_sid как вы это делали, и PHP будет заботиться об идентификаторе.

В противном случае вы должны сохранить идентификатор вручную, например:

<?php echo 'mypage.php?'.htmlspecialchars(SID); ?>
  • 1
    В цитируемом вами тексте написано «Если вы не используете PHP 4.2.0 или более позднюю версию», а не «или более раннюю». Любая версия, к которой относится инструкция, принадлежит музею.
  • 0
    Ты прав. Это было ошибкой в рассуждениях ... Я был совершенно уверен, что новые версии PHP по умолчанию отключают trans_sid , а не наоборот. Я расширил свой ответ.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню