Есть ли способ объединить поведение SESSION_EXPIRE_AT_BROWSER_CLOSE и SESSION_COOKIE_AGE - PullRequest
9 голосов
/ 14 февраля 2012

В целях безопасности я установил для SESSION_EXPIRE_AT_BROWSER_CLOSE значение true.

Но у файлов cookie длины браузера (файлы cookie, срок действия которых истекает, как только пользователь закрывает свой браузер), не имеют времени истечения, тогда SESSION_COOKIE_AGE не имеет эффектов (Да, я проверяю это) , Но я хочу установить выход / тайм-аут по неактивности плюс выход при закрытии просмотра.

Мой вопрос: Каков наилучший способ реализовать таймаут / неактивность при бездействии в сценариях cookie длины браузера?

1 Ответ

18 голосов
/ 15 февраля 2012

Как вы объясняете, SESSION_EXPIRE_AT_BROWSER_CLOSE и SESSION_COOKIE_AGE не совместимы. Когда вы устанавливаете дату истечения срока действия куки-файла, этот куки-файл не становится куки-файлом длины браузера.

Затем, чтобы достичь желаемого поведения, вы должны установить SESSION_EXPIRE_AT_BROWSER_CLOSE в значение True и тайм-аут управления истекает вручную .

Элегантный способ управления тайм-аутом истечения вручную:

  1. Создание нового пользовательского промежуточного программного обеспечения , управляющего временем ожидания.
  2. Измените settings.py, чтобы включить свое промежуточное программное обеспечение (и сеансы).

Пользовательское промежуточное ПО timeout может выглядеть следующим образом:

# updated version that should work with django 1.10 middleware style
# tested up to django 2.2

import time
from django.conf import settings


class SessionIdleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.user.is_authenticated:
            if 'last_request' in request.session:
                elapsed = time.time() - request.session['last_request']
                if elapsed > settings.SESSION_IDLE_TIMEOUT:
                    del request.session['last_request'] 
                    logout(request)
                    # flushing the complete session is an option as well!
                    # request.session.flush()  
            request.session['last_request'] = time.time()
        else:
            if 'last_request' in request.session:
                del request.session['last_request']

        response = self.get_response(request)

        return response

Решение для древних версий Django (до 1.10)

class timeOutMiddleware(object):

    def process_request(self, request):
        if request.user.is_authenticated():
            if 'lastRequest' in request.session:            
                elapsedTime = datetime.datetime.now() - \
                              request.session['lastRequest']
                if elapsedTime.seconds > 15*60:
                    del request.session['lastRequest'] 
                    logout(request)

            request.session['lastRequest'] = datetime.datetime.now()
        else:
            if 'lastRequest' in request.session:
                del request.session['lastRequest'] 

        return None

Не забудьте включить сессий , чтобы сохранить lastRequest.

Это решение написано и проверено мной и теперь работает на моем сайте. Этот код имеет лицензию GNU;)

Новое на django 1.6 (... два года спустя ...)

Значения даты и времени могут быть сериализуемы, только если вы используете PickleSerializer . Если нет, возможно, простое решение - перевод даты и времени в метку времени unix и обратно . Не стесняйтесь размещать сообщения под этим переводом.

Отредактировано

Приложение

django-session-security предоставляет механизм выхода из системы неактивных аутентифицированных пользователей. Посмотри.

...