From 611d0b71e81079ed7d159a1025f2261944693aa9 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 3 Apr 2024 16:41:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=B8=8B=E7=BA=BF=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98=20SESSIO?= =?UTF-8?q?N=5FEXPIRE=5FAT=5FBROWSER=5FCLOSE=20=E5=8F=AF=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20(#12936)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/audits/api.py | 2 +- apps/authentication/api/session.py | 2 +- apps/authentication/signal_handlers.py | 6 ++---- apps/common/sessions/cache.py | 11 +++++++---- apps/settings/serializers/security.py | 4 ++++ 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/audits/api.py b/apps/audits/api.py index 80d5d5310..aa6a96fdb 100644 --- a/apps/audits/api.py +++ b/apps/audits/api.py @@ -287,6 +287,6 @@ class UserSessionViewSet(CommonApiMixin, viewsets.ModelViewSet): keys = queryset.values_list('key', flat=True) for key in keys: - user_session_manager.decrement_or_remove(key) + user_session_manager.remove(key) queryset.delete() return Response(status=status.HTTP_200_OK) diff --git a/apps/authentication/api/session.py b/apps/authentication/api/session.py index b8885b4d3..3cf27329b 100644 --- a/apps/authentication/api/session.py +++ b/apps/authentication/api/session.py @@ -26,7 +26,7 @@ class UserSessionManager: user_session_manager.add_or_increment(self.session.session_key) def disconnect(self): - user_session_manager.decrement_or_remove(self.session.session_key) + user_session_manager.decrement(self.session.session_key) if self.should_delete_session(): thread = Thread(target=self.delay_delete_session) thread.start() diff --git a/apps/authentication/signal_handlers.py b/apps/authentication/signal_handlers.py index 943d751dd..e060e3c1f 100644 --- a/apps/authentication/signal_handlers.py +++ b/apps/authentication/signal_handlers.py @@ -1,5 +1,3 @@ -from importlib import import_module - from django.conf import settings from django.contrib.auth import user_logged_in from django.core.cache import cache @@ -8,6 +6,7 @@ from django_cas_ng.signals import cas_user_authenticated from apps.jumpserver.settings.auth import AUTHENTICATION_BACKENDS_THIRD_PARTY from audits.models import UserSession +from common.sessions.cache import user_session_manager from .signals import post_auth_success, post_auth_failed, user_auth_failed, user_auth_success @@ -32,8 +31,7 @@ def on_user_auth_login_success(sender, user, request, **kwargs): lock_key = 'single_machine_login_' + str(user.id) session_key = cache.get(lock_key) if session_key and session_key != request.session.session_key: - session = import_module(settings.SESSION_ENGINE).SessionStore(session_key) - session.delete() + user_session_manager.remove(session_key) UserSession.objects.filter(key=session_key).delete() cache.set(lock_key, request.session.session_key, None) diff --git a/apps/common/sessions/cache.py b/apps/common/sessions/cache.py index 6b05b5e5e..f15ddb6ae 100644 --- a/apps/common/sessions/cache.py +++ b/apps/common/sessions/cache.py @@ -35,13 +35,16 @@ class RedisUserSessionManager: def add_or_increment(self, session_key): self.client.hincrby(self.JMS_SESSION_KEY, session_key, 1) - def decrement_or_remove(self, session_key): - new_count = self.client.hincrby(self.JMS_SESSION_KEY, session_key, -1) - if new_count <= 0: - self.client.hdel(self.JMS_SESSION_KEY, session_key) + def decrement(self, session_key): + self.client.hincrby(self.JMS_SESSION_KEY, session_key, -1) def remove(self, session_key): self.client.hdel(self.JMS_SESSION_KEY, session_key) + try: + session_store = import_module(settings.SESSION_ENGINE).SessionStore(session_key) + session_store.delete() + except Exception: + pass def check_active(self, session_key): count = self.client.hget(self.JMS_SESSION_KEY, session_key) diff --git a/apps/settings/serializers/security.py b/apps/settings/serializers/security.py index 1fca3be3d..d1c252a28 100644 --- a/apps/settings/serializers/security.py +++ b/apps/settings/serializers/security.py @@ -196,6 +196,10 @@ class SecuritySessionSerializer(serializers.Serializer): label=_('Connection max idle time (minute)'), help_text=_('If idle time more than it, disconnect connection.') ) + SESSION_EXPIRE_AT_BROWSER_CLOSE = serializers.BooleanField( + required=False, default=False, label=_('Session expire at browser closed'), + help_text=_('Whether to expire the session when the user closes their browser.') + ) SECURITY_MAX_SESSION_TIME = serializers.IntegerField( min_value=1, max_value=99999, required=False, label=_('Session max connection time (hour)'),