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

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

Код (условно, без неимеющего к вопросу отношения):
index.php
session_start(['cookie_lifetime' => 0]);
login.php

При закрытии вкладки/браузера или перезапуске веб-сервера, сессия не удаляется. Она вечная остаётся, так как при открытии браузера - она же обновляется.

php.ini:

Пробовал через JS:

и так

Менял unload на beforeunload - ничего. Изменения асинхронного запроса на синхронный - тоже ничего не дают.
При закрытии вкладки/или браузера - код logout.php не выполняется.

Код logout.php (при обращении к скрипту в адресной строке - он работает успешно):

Как добиться результата из вопроса? P.S. session.gc_maxlifetime = 0 тоже не даёт результата.

Дополнительно:

Понаблюдайте какой php-шный session_id выделяется сервером при работе с login.php и logout.php. Если эти скрипты запускаются из какой-нибудь CMS, то встречал ситуации, что у них разные идентификаторы, отсюда то, что сессия не уничтожается правильно.

  • Один и тот-же phpsessid. Не CMS.
  • Ответы:

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

    Upd: а вас не устроит установить сессию на минуту, например?

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

      Установлена ли сессия на минуту или на год - роли не играет, если браузер её запоминает. В моём случае, как я выше написал - не помогает ничего, не простой машины (истечение времени жизни сессии), не перезапуск компьютера или веб-сервера. При открытии страницы - сессия жива. С чем это связанно - не могу понять. В коде кроме session_start, ничего больше нет. Почему JS не срабатывает - тоже понять не могу. При чём если использовать beforeunload return "same text", то после клика мышкой по телу сайта, при попытке закрыть/обновить страницу - браузер таки спрашивает, а точно ли я хочу покинуть страницу, но при любом другом коде - не происходит ничего.

    • MZhack, запрос в beforeunload просто не успевает отработать.
      https://css-tricks.com/send-an-http-request-on-pag...
    • MZhack, а вы устанавливаете session.use_strict_mode=true? Судя по описанию - как раз то, что вам настоятельно необходимо!

      И по логике, закрытие всех вкладок с сайтом должно удалять cookie_lifetime=0, потому что это по сути закрытие браузера для конкретного сайта. Проверяйте cookie в самом браузере, хранятся, не хранятся?

    • Stalker_RED, не понимаю, как заставить работать в моём случае?
    • AUser0, session.use_strict_mode установил в true, ничего не изменилось.

      В браузере остаётся сессия и никуда не пропадает. Удаляется только если выполнить logout.php (вручную).

    • MZhack, отправить через sendBeacon, например. Но Он же все равно не всегда будет отрабатывать, это решение не может быть основным механизмом. сам подход неплохо бы пересмотреть.
    • Stalker_RED, так в том то и вопрос, что js не работает (гарантированно или нет) и php сессия не умирает, хотя должна. И какой тогда подход смотреть? Просто перед тем, как переходить к другим решениям, хочется понимать, почему не работает моё.
    • MZhack, use_strict_mode при чем тут вообще? Это чтобы юзеры не могли сами себе session id придумывать.
    • MZhack, вы для начала сравните "какого эффекта я хочу добиться" и "что вообще умеют эти ваши браузеры". Мне кажется вы забираетесь в область невозможного.

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

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

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

      Часть этих вопросов вы можете решить создав постоянное соединение с сервером, и следя за ним. Через вебсокет какой-нибудь. Но опять-же не все.

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

    • Stalker_RED, я может быть как-то не так объясняю, что мне нужно. Опишу в виде ситуационного примера: на рабочем месте с компьютера на сайт логинется user1, делает свои дела, закрывает браузер и уходит пить кофе. Пока он пьёт кофе, за компьютер садится другой человек, открывает браузер и получает доступ к сайту от имени user1. Нужно сделать, чтобы этого не происходило. То есть любой человек заного открывающий браузер вынужден был авторизовываться по-новому. Я так понимаю, что за это отвечает cookie_lifetime, но любое значение этого параметра, будь-то 0 или какое-то время - почемуто ничего не меняет. Сессия остаётся жива, даже спустя неделю и более, и даже при перезагрузке софта или железа. Как реализовать допустим, как в примере с банком, как вы говорите?
    • MZhack, тут явно что-то не так. Закрытие браузера (и я предполагаю, закрытие последней вкладки с сайтом) однозначно должно стирать куки (при нулевой lifetime). Так в доках же написано! Вот точно что-то не так.

      P.S. В случае с банком всё просто - банк как минимум стирает сессию через XX минут неактивности, и кука становится бесполезной. Но должны использовать и механизм удаления по закрытию.

    • MZhack, я психанул и запилил огромній пример
      stalkerred.xtreemhost.com/test_session_expire.php

      по кнопке show src видно весь говнокод внутри.
      Вся суть этого примера в примерно пяти строчках

      В этом примере SESSION_TIME_LIMIT установлен на 20 секунд, но вы можете установить 3 минуты, или илюбое другое время, которое вам покажется разумным.
      И вам плевать на куки, gc_probability и прочую кухню. вы просто сравниваете две цифры, и если время прошло - logout.
      И плевать на окно браузера и его вкладки.

    • MZhack, проверил на первом попавшемся сайте online.sberbank.ru. Даже просто открытие этого сайта создаёт 6-7 куков "до закрытия". И нет, они не стираются при закрытии последней вкладки. Но стираются при закрытии браузера.
    • AUser0, в хроме "восстановить закрытые вкладки?" восстановит их вместе с куками.
      А расширение session buddy восстановит их хоть через год. Отследить закрытие вкладки или окна технически невозможно: прекращение активности от вкладки не значит, что она закрыта, она может "спать". При закрытии хрома через taskkill, например, он никаких сигналов не отправит, и при следующем включении предложит восстановить вкладки даже при настройках по умолчанию.
      Вывод - следить надо на сервере, учитывая время неактивности.
    • Stalker_RED, для браузера Firefox существует аддон Cookie Exterminator. И вот этот аддон прекрасно замечает закрытие "последней" вкладки, сразу удаляя cookie сайта(ов), не добавленного в исключения.

      И вопрос, как тогда онлайн-банки выставляют "Expire: At end of session" своим cookie, и браузер это понимает? Подпольный сговор банкиров с производителями браузеров?

    • AUser0, это кука с expire=0
      И то что оно как-то в фаерфоксе себя ведёт - не показатель. Оно может по другому вести себя в опере, сафари, мобильном хроме.
      Вот я пруфлинк даже принёс https://stackoverflow.com/questions/4132095/when-d...

      Юзер может вообще поставить не "стандартный" браузер, взять исходники хромиума, подправить работу с куками,и собрать.
      Все эти таймеры, cors и httponly - защита не от клиента-злоумышленника, а чтобы сложнее было устроить атаку на невиновного.
      Ну да ладно, я ушёл от темы.

      На самом деле, вопрос с доступом к учётке на перекуре решается административно. Пишется должностная инструкция, мол "уходя нажми WIN+L", и кто не нажал - сам дурак.
      А надёжно обнаружить закрытие вкладки НЕВОЗМОЖНО технически.
      Разве что в фоне пинговать, и отслеживать что пинг пропал. Но опять-же, это никак не отличить от "комп уснул" или "пропал интернет".

      Остаётся возня с сервер-сайд таймерами, которым плевать на наличие вкладок.

    Могу лишь предложить такую логику. Нужно поставить жизнь сессии пять минут. Каждый раз, пока пользователь на сайте, будет обновляться жизнь сессии. Когда пользователь закроет вкладку или окно, то сессия больше обновляться не будет. Соответственно она удалится.

    • Так и должно быть, но сессия всё равно почему-то остаётся вечной, даже если задать время отличное от нуля.

    А если так? Через js использовать sessionStorage, записать туда какой-то ключ и при запросах его передавать?
    Как хранить что-то в браузере, только пока открыта вкладка
    Почитайте.

    • Читаю, изучаю, скорее всего воспользуюсь. Но всё равно очень интересно, почему не работает "стандартными" методами.

     

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

     

      • Как удалить сессию при закрытии вкладки/окна браузера?Есть ответ
      • 07.04.2024
      Ответить

      Для удаления сессии при закрытии вкладки или окна браузера можно использовать JavaScript. Вот пример кода:

      Этот код будет выполняться перед закрытием вкладки или окна браузера, и при этом будет удалять текущую сессию. Таким образом, пользователь будет выйти из сессии при закрытии вкладки.

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

    Оставить комментарий