Сеанс PHP истекает немедленно, когда часы клиента установлены в будущем

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

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

По какой-то причине я взглянул на компьютерные часы пользователя и … удивил! Его часы были в 3 месяца в будущем! Я не знал, может ли такая вещь иметь какое-либо отношение к провалу, но я исправил часы. Тем не менее это не сработало. Я удалил все файлы cookie. Еще ничего. Поэтому я перезапустил браузер, а затем снова начал работать!

Ближайшей информацией, которую я получил по этому вопросу, был ответ Шимона Амита на этот вопрос . Хорошо, теперь я знаю, что причина «неправильной конфигурации» часов. Проблема в том, что … Я не могу контролировать компьютерные часы каждого клиента. Некоторые из них могут иметь свои компьютерные часы, установленные в будущем.

Мой вопрос : есть ли решение для этого? Любой трюк? Я не хочу, чтобы клиенты сталкивались с такими ошибками, поскольку они могут найти это «хромым» и нарушить их доверие к приложению, хотя это не моя ошибка (в некотором смысле).

Solutions Collecting From Web of "Сеанс PHP истекает немедленно, когда часы клиента установлены в будущем"

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

EDIT: опция Javascript

Это общий взлом, но вы можете использовать javascript для получения текущего времени на клиентской машине и отправки его на сервер, а затем настроить тайм-аут в вашем cookie сеанса, чтобы истечь через три месяца после этого. См. http://www.w3schools.com/jsref/jsref_gettime.asp

После того как вы получили время клиента, вы можете сбросить истечение сеанса с помощью session_cache_expire (). http://www.php.net/manual/en/function.session-cache-expire.php

EDIT: 100% -ная опция на стороне сервера

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

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

Я полностью согласен с комментарием @ MarcB, что вы не можете взять на себя ответственность за то, насколько грубо неправильно сконфигурирована машина пользователя. Если вы действительно хотите изменить ситуацию в этом отношении, я бы предложил использовать PHP для вывода небольшого фрагмента javascript, который включает время на сервере. Этот фрагмент сравнивал бы время со временем на клиентском компьютере и повышал бы оповещение, если время отличается от X на сервере. [скажем, 24 часа или около того]

Любой трюк?

Используйте сеансовые куки. Не сеанс в значении сеансов PHP, а сеанс браузера. Файлы cookie сеанса хранятся до тех пор, пока пользователь не закроет браузер. Они невосприимчивы к тем часам, которые пользователь установил для своего компьютера. Они будут действовать до тех пор, пока браузер не будет закрыт.

Обычно это подходит для файлов cookie, связанных с PHP-сессией.

Для PHP вам необходимо убедиться, что время жизни файла cookie сеанса настроено на 0 до начала сеанса. Это либо установка ini session.cookie_lifetime либо вызов функции session_set_cookie_params .

Более подробное описание параметров cookie см. В документации по функции setcookie .

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

Проверьте их, например, если сессия слишком старая, последняя активность слишком давно и т. Д., Уничтожьте сеанс и заставите пользователя снова войти в систему.

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

Попробуйте отключить тайм-аут сеанса или, по крайней мере, установить его далеко в будущее. Это должно делать свое дело.