Перейти к содержимому

Слетает авторизация - время жизни сессии и запоминание входа

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

Решение

Смотрим оба предела времени жизни сессии:

// предел PHP: после него сессия удаляется сборщиком мусора
printf("php: %s сек\n", ini_get('session.gc_maxlifetime'));
// предел платформы: своё ограничение поверх сессии PHP
printf("сайт: %s мин\n", COption::GetOptionString('main', 'session_timeout', '24'));

Пределов два, и работает меньший из них. Настройка на сайте не спасёт, если сборщик мусора PHP удаляет файл сессии раньше, и это первая причина «поставил час

  • всё равно выкидывает».

Продлеваем сессию:

COption::SetOptionString('main', 'session_timeout', '120'); // минуты
// и предел PHP, иначе он останется главным
ini_set('session.gc_maxlifetime', 7200);

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

Включаем запоминание входа:

// «запомнить меня» кладёт долгоживущую метку, не зависящую от сессии
COption::SetOptionString('main', 'auth_multisite', 'N');
COption::SetOptionString('main', 'controller_member', 'N');
$USER->Login($login, $password, 'Y'); // третий аргумент - запоминание

Запоминание входа работает мимо сессии: пользователь возвращается на сайт через неделю и остаётся авторизованным. Сессия при этом создаётся заново, и время её жизни на это не влияет.

Разбираемся, почему выкидывает из админки:

Окно терминала
# каталог сессий: проверяем права и наличие места
php -i | grep -E 'session.save_path|session.cookie_'
ls -ld /var/lib/php/session/ && df -h /var

Недоступный на запись каталог сессий выглядит именно как случайный выход из админки. Второй частый случай - разные адреса сайта: вход по адресу с поддоменом и без него даёт две разные метки.

Сбрасываем пароль администратора с сервера:

// /home/bitrix/www/reset.php - кладём, запускаем один раз и сразу удаляем
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
$user = new CUser();
$user->Update(1, ['PASSWORD' => $new, 'CONFIRM_PASSWORD' => $new]);
echo $user->LAST_ERROR ?: 'пароль изменён';

Потерянный пароль администратора восстанавливают именно так. Штатное восстановление по почте требует работающей отправки писем, поэтому надёжнее скрипт, который меняет пароль напрямую через API, - его кладут в корень сайта, запускают один раз и сразу удаляют.

Жалоба «слетает авторизация» почти всегда распадается на три разных случая: короткая сессия, недоступный каталог сессий и расхождение адресов. Первый проверяется настройками, второй - правами на каталог, третий - сравнением адреса в строке браузера с адресом в настройках сайта. Дальше разбор идёт по одной ветке, а не по всем сразу.

Многосайтовость добавляет своё: вход на одном сайте пула по умолчанию не переносится на другой. Общая авторизация включается отдельной настройкой, и без неё сотрудники честно логинятся дважды.

Типичные проблемы

Сессия обрывается раньше заданного времени.

Предел PHP меньше настройки сайта. Работает меньший из двух, и менять нужно оба.

Из админки выкидывает случайно.

Каталог сессий недоступен на запись или на разделе кончилось место. Файл сессии просто не сохраняется.

Вход не переносится между поддоменами.

Метка авторизации привязана к адресу. Для общего входа задают область действия на весь домен.

После входа снова показывается форма.

Не сохраняется метка авторизации: браузер её отклоняет или адрес сайта в настройках отличается от адреса в строке браузера.

Запоминание входа не работает.

Оно не включено при входе либо срок хранения метки истёк. Сессия и запоминание - два независимых механизма.

Частые вопросы

Сколько держать сессию администратора?

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

Как выйти на всех устройствах сразу?

Сменой пароля: она снимает сохранённые метки авторизации. Отдельного управления списком сеансов в базовой поставке нет.

Почему сессия живёт дольше, чем задано?

Сборщик мусора PHP запускается вероятностно, а не по расписанию. Файл сессии может пережить свой срок до ближайшей уборки.

Что делать, если потерян пароль администратора?

Сменить его скриптом с сервера через API и сразу удалить скрипт. Прямая правка таблицы не подходит: пароль хранится необратимо и с солью.

Смежное

Первоисточник