Странный, раздражающий и очень случайный тайм-аут сеанса

У меня есть довольно большое PHP-приложение (несколько тысяч уникальных URL-адресов, логины пользователей с различными ролями и т. д.). PHP имеет тайм-аут сеанса, установленный на 1 час (3600 секунд) в php.ini. Вход в систему работает следующим образом: когда пользователь успешно входит в приложение, в $_SESSION сохраняется несколько сведений о пользователе, включая имя пользователя, настоящее имя, идентификатор роли и т. д. При доступе к каждой странице (общий код) $ _SESSION проверяется на наличие этих переменных и, если они присутствуют, пользователь переходит туда, куда он просил. Если переменных нет, то пользователь перенаправляется на страницу «не авторизованный».

Это работало нормально в течение последних нескольких лет и до сих пор работает нормально - в основном. Очень случайно сеанс сеанса, кажется, истекает без каких-либо предупреждений или чего-либо еще. Для вошедшего в систему пользователя это выглядит так: войдите в систему, сделайте что-нибудь, перейдите на следующую страницу — и вместо этого выйдите из системы и вернитесь на страницу «не вошедшей в систему». Естественно, это крайне раздражает. Однако случайный характер этого поведения чрезвычайно затрудняет его исследование.

Я никогда не сталкивался с этим на своей машине ни в одном браузере. В офисе есть еще одна машина, где это постоянно происходит в каждом браузере (по крайней мере, я могу воспроизвести проблему). На еще одной машине это происходит в одном браузере и не происходит в другом браузере. И все же на другой машине это происходит иногда, а иногда нет. Сегодня нам позвонил один из клиентов, у которого возникла эта проблема, но когда его попросили попробовать в другом браузере, все сработало нормально.

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

На данный момент любая помощь более чем приветствуется.

ДОБАВЛЕНО: вот часть session моего php.ini:

[Session]
session.save_handler = files
session.use_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly = 
session.serialize_handler = php
session.gc_divisor     = 100
session.gc_maxlifetime = 3600 
session.bug_compat_42 = 1
session.bug_compat_warn = 1
session.referer_check =
session.entropy_length = 0
session.entropy_file =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 4

person Aleks G    schedule 19.04.2012    source источник
comment
Предполагая, что сеансы используют файлы cookie, перейдите в поле, которое воспроизводит проблему, подключите хороший прокси-сервер HTTP, например Fiddler. и посмотрите, не является ли запрос, который идет не так, необычным. Это скажет вам, находится ли проблема на стороне клиента или на стороне сервера (или, возможно, это комбинация факторов), и, возможно, даст вам большое преимущество для подражания.   -  person Jon    schedule 19.04.2012
comment
Кстати, это обычно происходит со старыми машинами. Обе машины в офисе, которые более или менее постоянно проявляют проблему, старше 3 лет. Пожалуйста, не предлагайте обновить аппаратное обеспечение, так как большинство наших клиентов являются государственными учреждениями и используют аппаратное/программное обеспечение на много лет позже, чем остальные из нас. У нас была огромная негативная реакция (и мы потеряли крупного клиента), когда мы прекратили поддержку IE6 всего несколько месяцев назад.   -  person Aleks G    schedule 19.04.2012
comment
какой обработчик сеанса вы используете?   -  person WayneC    schedule 19.04.2012
comment
@wgcrouch У меня есть session.save_handler = files и session.serialize_handler = php   -  person Aleks G    schedule 19.04.2012
comment
Я предполагаю, что срок действия вашего файла cookie истекает из-за какого-то странного поведения в этих браузерах. Вы должны проверить, остается ли файл cookie на месте, когда сеанс теряется...   -  person bardiir    schedule 19.04.2012
comment
Почему бы не написать скрипт, который пересохраняет сессию каждый раз, когда они переходят на новую страницу, а также сохраняет ее каждые 15 минут.   -  person nathan hayfield    schedule 17.10.2012


Ответы (1)


Я столкнулся с теми же проблемами со случайным временем ожидания сеансов на некоторых компьютерах, постоянно на других и совсем не на большинстве. После долгих проб и ошибок я отследил свою проблему на некоторых машинах с IE, у которых были проблемы с компактной политикой конфиденциальности. Мы просто добавили такой заголовок («P3P: CP=Посетите www.oururl.tld для ознакомления с нашей Политикой конфиденциальности»), что устранило множество проблем старого IE. Предполагается, что это относится только к сторонним файлам cookie, но кто знает, что с IE.

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

Наконец, мне пришлось взять на себя установку времени ожидания сеанса из php, потому что часовой пояс нашего сервера вызывал проблемы, когда он устанавливался автоматически. Я просто устанавливаю срок действия равным 0, чтобы он никогда не истекал сроком действия файла cookie с использованием браузера до тех пор, пока «сеанс» не завершится, когда пользователь закроет браузер или что-то в этом роде. Затем я добавил в сеанс переменную просто expires и вручную проверил ее, чтобы все проверки и решения об истечении срока действия принимались в часовом поясе нашего сервера, а не клиентов.

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

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

person Reid Johnson    schedule 31.10.2012