Истечение сеанса Django в определенное время для конкретного пользователя (например, когда заканчивается его смена) при входе в систему - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть система, в которой работают сменные рабочие 24/7.В настоящее время нередко забывают выходить из системы, а следующий работник берет свой сеанс и работает с ним.Это вызывает некоторые проблемы с подотчетностью.

Я понимаю, что есть варианты для продолжительности сеанса, т.е. settings.SESSION_COOKIE_AGE, но они немного тупы для наших целей.У нас есть разные работники с разной продолжительностью смены, менеджеры, у которых есть 2FA в действии, и это просто не тот путь, которым мы хотим следовать.Проще говоря ...

Я хочу программно установить время смерти сеанса при входе в систему.

У нас уже есть настраиваемое представление входа в систему, но оно всплывает через встроенныйв django.contrib.auth.forms.AuthenticationForm.И даже там я не вижу, как установить срок действия для конкретного сеанса.

Есть предложения?

Редактировать : request.session * .get_expiry_age() иset_expiry(value) кажется уместным , но они действительно обновляются, потому что они циклически изменяются в зависимости от того, когда сеанс был последний раз изменен, а не от того, когда сеанс начался.Мне нужно что-то, что устанавливает максимальный возраст сессии.

Редактировать 2 : Я думаю, я мог бы записать в сеанс при входе в систему и выполнить что-то внешне (cronnedуправление), которое проверило истечение срока действия (если существовало) и обстреливало каждый сеанс, который истек.

1 Ответ

1 голос
/ 16 апреля 2019

Придумал ответ благодаря комментариям. При входе в систему я вставляю метку времени в сеанс:

request.session['login_timestamp'] = timezone.now().timestamp()

Если вам интересно, почему отметка времени, а не datetime.datetime.now() или timezone.now(), кодировщик сеансов Django по умолчанию использует JSON, а кодировщик JSON Django не обрабатывает даты и время. Это можно обойти, написав кодировщик, который может обрабатывать дату и время ... Но мне достаточно целочисленного значения секунд с момента появления.

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

from django.contrib.auth import logout

class MyMiddleware(object):

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

    def __call__(self, request):
        # other checks to make sure this middleware should run.
        # eg, this only happens on authenticated URLs

        login_timestamp_ago = timezone.now().timestamp() - request.session.get('login_timestamp', timezone.now().timestamp())

        if settings.RECEPTION_LOGIN_DURATION and <insert user checks here> and login_timestamp_ago >= settings.RECEPTION_LOGIN_DURATION:
            logout(request)  # nukes session
            messages.warning(request, "Your session has expired. We need you to log in again to confirm your identity.")
            return redirect(request.get_full_path())

Порядок событий здесь очень важен. logout(request) уничтожает весь сеанс. Если вы напишите сообщение (сохраненное в сеансе) заранее, оно будет отсутствовать после logout(request).

...