Пользователя выбрасывает из админки: сессии в PHP и Yii2

Когда пользователя выбрасывает из админки, проблема редко выглядит очевидной. Авторизация проходит, но через минуту снова просит логин. Или в одном браузере всё нормально, а в другом сессия слетает. Иногда это связано с кодом, но часто причина в cookies, session path, HTTPS, Redis, правах на runtime или настройках домена.

Сначала понять сценарий

Важно отделить разные проблемы. Пользователь вообще не может войти — это одно. Входит, но сразу выходит — другое. Сессия живёт несколько минут — третье.

  • авторизация не проходит совсем;
  • после логина сразу возвращает на форму входа;
  • сессия слетает после перехода на другой раздел;
  • сессия слетает после закрытия браузера;
  • проблема только на www или только без www;
  • проблема появилась после HTTPS или переезда.

Проверить cookies в браузере

В DevTools нужно посмотреть, создаётся ли cookie сессии после входа. Обычно это PHPSESSID или имя, заданное в конфиге Yii2.

Нужно проверить:

  • domain;
  • path;
  • expires или session;
  • secure;
  • httpOnly;
  • sameSite.

Если cookie не сохраняется, backend может работать правильно, но браузер не будет отправлять сессию обратно.

Домен и www

Если сайт открывается и через www, и без www без редиректа, сессии могут выглядеть сломанными. Пользователь вошёл на example.ru, а следующий переход ушёл на www.example.ru — cookie уже другая.

curl -I https://example.ru/
curl -I https://www.example.ru/

Лучше выбрать основной домен и настроить 301 со второго варианта.

HTTPS и secure cookie

Если у cookie стоит secure, браузер будет отправлять её только по HTTPS. Это правильно для рабочего сайта, но проблема появится, если часть ссылок ведёт на HTTP.

'session' => [
    'cookieParams' => [
        'httpOnly' => true,
        'secure' => true,
        'sameSite' => yii\web\Cookie::SAME_SITE_LAX,
    ],
],

После включения secure нужно убедиться, что весь сайт действительно редиректит на HTTPS.

Права на файлы сессий

Если PHP хранит сессии в файлах, веб-сервер должен иметь право писать в session.save_path. На хостингах путь может отличаться.

php -i | grep session.save_path
ls -la /var/lib/php/sessions

Если сессии настроены через Yii2 в runtime, нужно проверить права на runtime.

ls -la runtime
ls -la runtime/sessions

Redis или база для сессий

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

'session' => [
    'class' => 'yii\redis\Session',
    'redis' => 'redis',
],

Если Redis используется одновременно для кэша, очередей и сессий, нельзя бездумно выполнять flushdb. Можно случайно удалить активные сессии пользователей.

Время жизни сессии

Если сессия слетает слишком быстро, нужно проверить timeout в Yii2 и настройки PHP.

'user' => [
    'identityClass' => 'app\models\User',
    'enableAutoLogin' => true,
    'authTimeout' => 3600,
],

authTimeout задаёт время бездействия. Если включён auto login, дополнительно проверяется identity cookie.

Балансировщик или несколько серверов

Если сайт работает на нескольких серверах, файловые сессии могут ломаться: пользователь вошёл на одном сервере, следующий запрос попал на другой, а там файла сессии нет. В таком случае используют общее хранилище сессий: Redis, Memcached или базу.

Для небольшого проекта это встречается редко, но после переноса на новую инфраструктуру такое стоит проверить.

Логи

В логах стоит искать ошибки записи сессий, проблемы Redis, warning по headers already sent и исключения авторизации.

tail -n 150 runtime/logs/app.log
tail -n 150 /var/log/php-fpm/error.log

headers already sent может мешать установке cookie, если вывод начался раньше, чем приложение отправило заголовки.

Чек-лист диагностики

  1. Проверить, создаётся ли cookie после логина.
  2. Проверить domain и path cookie.
  3. Проверить редирект www и non-www.
  4. Проверить полный переход на HTTPS.
  5. Проверить session.save_path и права.
  6. Проверить Redis или базу, если сессии хранятся там.
  7. Проверить authTimeout и auto login.
  8. Посмотреть логи PHP и Yii2.

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

Комментарии (0)

Пока нет комментариев. Будьте первым!