Подтвердить что ты не робот

Как продлить срок службы, когда пользователь активен?

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

Несомненно, сессия заканчивается, так как пользователь долгое время не работал. И даже если они простаивают, я добавил периодический запрос AJAX, так называемое сердцебиение, которое обновляет время доступа к сеансам и измененное время. Я даже добавил прикосновение ($ session_file) каждый раз, когда пользователь нажимает что-то или вызывается сердцебиение. Я также попытался восстановить идентификатор сеанса. Ничего не помогло.

И, к сожалению, до сих пор я не мог воспроизвести проблему локально, потому что это случается так часто, когда появляется больше запросов. Некоторые параметры php.ini:

session.use_cookies = 1
session.use_only_cookies = 1
session.cookie_lifetime = 0
session.gc_probability = 1
session.gc_divisor = 1500
session.gc_maxlifetime = 10800
4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Остальные страницы (включая ваше сердцебиение) возобновляют существующий сеанс, поэтому на этом этапе вы ищете указанное выше значение; если он отсутствует, вы можете сделать еще несколько проверок:

  • прошел сеанс cookie? если нет, проблема с браузером /cookie.
  • соответствует ли файл cookie сеанса session_id()? если нет, файл сеанса был потерян из-за сбора мусора.
  • существует ли известное значение в сеансе? если нет, сеанс был усечен или кто-то пытается атаковать принятие сеанса.
  • Знает ли известное значение cookie сеанса? если нет, сеанс был создан разными способами, чем cookie; вы можете проверить настройку session.use_only_cookies.

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

Ответ 3

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

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

Ответ 4

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

  • Добавить кодz
  • ОС-дистрибутив ОС и версия
  • Версия PHP

Есть ли у вас сеансовые проверки, которые полагаются на IP. Если это так, возможно, вы на самом деле используете прокси-сервер, который дает разные IP-адреса каждый раз так долго (например, Cloudflare), и в этом случае вы можете использовать HTTP_CF_CONNECTING_IP для получения фактически постоянного IP-адреса.

Я также заметил еще одну вещь:

session.use_only_cookies = 1
session.cookie_lifetime = 0

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

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

Редактирование разъяснений:

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

Ответ 5

Здесь что-то я использовал. Он использует javascript для "ping" сервера с интервалом в 10 минут.

<form method="POST" target="keepalive-target" id="keepalive-form">
    <input type="hidden" name="keepalive-count" id="keepalive-count">
</form>
<iframe style="display:none; width:0px; height:0px;" name="keepalive-target"></iframe>
<script>
    var kaCount=0;
    setInterval(function()
    {
        document.getElementById("keepalive-count").value=kaCount++
        document.getElementById("keepalive-form").submit();
    },600000);
</script>