Как истечь сессия из-за неактивности в Django?

Наше приложение Django имеет следующие требования управления сеансами.

  1. Сессии истекают, когда пользователь закрывает браузер.
  2. Сессии истекают после периода неактивности.
  3. Обнаружьте, когда сессия истекает из-за неактивности, и отобразите соответствующее сообщение пользователю.
  4. Предупредите пользователей о предстоящем истечении сессии несколько минут до конца периода неактивности. Наряду с предупреждением, предоставьте пользователям возможность расширить их сессию.
  5. Если пользователь работает над долгой деловой активностью в рамках приложения, которое не включает запросы, отправленные к серверу, сессия не должна тайм-аут.

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

Требование 1
Это требование легко реализовано установкой SESSION_EXPIRE_AT_BROWSER_CLOSE to True.

Требование 2
Я видел несколько рекомендаций использовать SESSION_COOKIE_AGE для установки периода истечения сессии. Но этот метод имеет следующие проблемы.

  • Сессия всегда истекает в конце SESSION_COOKIE_AGE, даже если пользователь активно использует приложение. (Это может быть предотвращено путем установки истечения сессии на SESSION_COOKIE_AGE по каждому запросу с помощью пользовательского промежуточного программного обеспечения или путем сохранения сессии по каждому запросу установкой SESSION_SAVE_EVERY_REQUEST к истинному. Но следующая проблема неизбежна из-за использования 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).

Любое понимание будет высоко цениться.

84
задан Akbar ibrahim 11 June 2010 в 15:44
поделиться

1 ответ

Вот идея... Истечение сессии при закрытии браузера с помощью настройки SESSION_EXPIRE_AT_BROWSER_CLOSE. Затем установите временную метку в сессии при каждом запросе, например.

request.session['last_activity'] = datetime.now()

и добавьте промежуточное ПО для определения истечения срока действия сессии. Что-то вроде этого должно обрабатывать весь процесс...

from datetime import datetime
from django.http import HttpResponseRedirect

class SessionExpiredMiddleware:
    def process_request(request):
        last_activity = request.session['last_activity']
        now = datetime.now()

        if (now - last_activity).minutes > 10:
            # Do logout / expire session
            # and then...
            return HttpResponseRedirect("LOGIN_PAGE_URL")

        if not request.is_ajax():
            # don't set this for ajax requests or else your
            # expired session checks will keep the session from
            # expiring :)
            request.session['last_activity'] = now

Затем вам просто нужно сделать несколько урлов и представлений для возврата соответствующих данных в ajax-вызовы относительно истечения срока действия сессии.

Когда пользователь решит, так сказать, "обновить" сессию, все, что вам нужно сделать, это установить requeset.session['last_activity'] на текущее время

Очевидно, что этот код - только начало... но он должен вывести вас на правильный путь

41
ответ дан 24 November 2019 в 08:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: