Установить cookie сеанса только тогда, когда пользователь вошел в систему

Я создаю приложение на основе ZF3 и пытаюсь установить файл cookie сеанса только, когда пользователь успешно вошел в систему. И удалить его при выходе из системы.

Кажется, в сеансе ZF3 такой функции нет, или, по крайней мере, я не смог найти ее в конфигурация zend-session.

Прямо сейчас фреймворк создает файл cookie сеанса PHPSESSID (имя по умолчанию), когда открывается любая страница и файл cookie сеанса не найден.

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

Я хочу изменить это поведение, чтобы модель генерации файлов cookie сеанса была следующей:

  • Не создавайте файл cookie сеанса, пока не произойдет действительный вход в систему. Просто обработайте сеанс как новый, но пропустите создание файла cookie.
  • Создайте файл cookie сеанса, когда пользователь входит в систему, со временем жизни, указанным в конфигурации.
  • Уничтожить cookie сеанса, когда пользователь выходит из системы.

Любые указатели приветствуются.


person Silviu G    schedule 17.03.2017    source источник
comment
Найдите, где находится session_start(), и найдите способ избежать этой процедуры, пока кто-то не войдет в систему... Проблема в том, что вы не можете получить доступ к суперглобальному сеансу, пока сеанс не будет запущен. Запуск его позже в вашем файле может вызвать проблемы ... Итак, вам сначала нужно аутентифицировать пользователя, а затем перенаправить на страницу с помощью ... POST (?) ..., который запускает сеанс? Мне действительно интересно, почему вы хотите сделать это таким сложным? И как вы узнаете, что кто-то вошел в систему, кроме как проверить, установлен ли файл cookie?   -  person Raphioly-San    schedule 17.03.2017


Ответы (1)


На тот случай, если кто-то задаст аналогичный вопрос.

Немного повозившись, я нашел решение, но также обнаружил некоторые нежелательные побочные эффекты.

Решение

Как указал Рафиоли-Сан в комментарии к вопросу, вам необходимо получить доступ к сеансу, чтобы определить, вошел ли пользователь в систему. Это означает, что вам нужно запускать сеанс каждый раз. Это, в свою очередь, генерирует файл cookie сеанса.

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

Выполнение

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

namespace Application;

class Module
{
    public function onBootstrap(MvcEvent $event) {
        $event->getApplication()
            ->getEventManager()
            ->attach(
                MvcEvent::EVENT_FINISH,
                function() use ($event){
                    // Stop if a user is logged in
                    $userLoggedIn = $event->getApplication()->getServiceManager()->get(AuthenticationService::class)->hasIdentity();

                    if ($userLoggedIn) {
                        return;
                    }

                    // Destroy session cookie
                    // Note: this is not the most elegant solution, but it will suffice for this example
                    $params = session_get_cookie_params();
                    setcookie(session_name(), '', 1, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
                    session_destroy();
                    session_write_close();
                },
                -999
            );
    }
}

Побочные эффекты

Уничтожение файла cookie сеанса нарушает как минимум компонент flash messenger, когда он используется для гостей.

Другие компоненты также могут работать неправильно.

Выводы

Я изучил это решение по просьбе администратора сервера, поскольку файлы cookie вызывают проблемы при использовании системы кэширования Varnish.

Хотя базовая реализация работает, я все еще изучаю побочные эффекты.

person Silviu G    schedule 23.03.2017