Наше приложение Django имеет следующие требования к управлению сеансом.
- Сеансы истекают, когда пользователь закрывает браузер.
- Сессии истекают после периода бездействия.
- Определите, когда сеанс истекает из-за бездействия, и отобразите соответствующее сообщение для пользователя.
- Предупредить пользователей о приближающемся истечении сеанса за несколько минут до окончания периода бездействия. Вместе с предупреждением предоставьте пользователям возможность продлить сеанс.
- Если пользователь выполняет длительную бизнес-активность в приложении, которая не связана с отправкой запросов на сервер, сеанс не должен истекать по таймауту.
После прочтения документации, кода Django и некоторых сообщений в блогах, связанных с этим, я пришел к следующему подходу к реализации.
Требование 1
Это требование легко реализовать, установив для SESSION_EXPIRE_AT_BROWSER_CLOSE значение True.
Требование 2
Я видел несколько рекомендаций по использованию SESSION_COOKIE_AGE для установки периода истечения срока действия сеанса. Но у этого метода есть следующие проблемы.
Сеанс всегда истекает в конце SESSION_COOKIE_AGE, даже если пользователь активно использует приложение. (Этого можно избежать, задав для истечения срока действия сеанса значение SESSION_COOKIE_AGE для каждого запроса с использованием специального промежуточного программного обеспечения или сохраняя сеанс при каждом запросе, задав для параметра SESSION_SAVE_EVERY_REQUEST значение true. Но следующая проблема неизбежна из-за использования SESSION_COOKIE_AGE.)
Из-за того, как работают файлы cookie, SESSION_EXPIRE_AT_BROWSER_CLOSE и SESSION_COOKIE_AGE являются взаимоисключающими, т.е. срок действия cookie истекает при закрытии браузера или по истечении указанного времени. Если используется SESSION_COOKIE_AGE и пользователь закрывает браузер до истечения срока действия cookie, cookie сохраняется, и повторное открытие браузера позволит пользователю (или кому-либо еще) войти в систему без повторной аутентификации.
Django полагается только на наличие cookie, чтобы определить, активен ли сеанс. Он не проверяет дату истечения срока действия сеанса, хранящуюся в сеансе.
Для реализации этого требования и решения проблем, упомянутых выше, можно использовать следующий метод.
- Не устанавливайте SESSION_COOKIE_AGE.
- Для каждого запроса установите дату окончания сеанса «текущее время + период бездействия».
- Переопределите process_request в SessionMiddleware и проверьте срок действия сеанса. Отменить сеанс, если он истек.
Требование 3
Когда мы обнаруживаем, что срок действия сеанса истек (в настраиваемом SessionMiddleware выше), установите атрибут запроса, чтобы указать истечение срока действия сеанса. Этот атрибут можно использовать для отображения соответствующего сообщения пользователю.
Требование 4
Используйте JavaScript для обнаружения бездействия пользователя, предоставления предупреждения, а также возможности продления сеанса. Если пользователь желает продлить сеанс, отправьте на сервер импульс поддержки активности, чтобы продлить сеанс.
Требование 5
Используйте JavaScript для обнаружения активности пользователя (во время длительной деловой операции) и отправки импульсов поддержки активности на сервер, чтобы предотвратить истечение срока сеанса.
Вышеупомянутый подход к реализации кажется очень сложным, и мне было интересно, может ли быть более простой метод (особенно для Требования 2).
Любые идеи будут высоко оценены.