Chcę ograniczyć zalogowanych użytkowników, aby mieli tylko jedną aktywną sesję, tj. Jeśli użytkownik zaloguje się z nowym identyfikatorem sesji, stara sesja powinna zostać zakończona. znalazłem dużo pomocy na SO już: here i hereZezwalanie tylko na jedną aktywną sesję na użytkownika w aplikacji Django
I wdrożone rozwiązanie middleware, z odrobiną dodatkowego sprawdzanie ...
class OnlyOneUserMiddleware(object):
"""
Middleware to ensure that a logged-in user only has one session active.
Will kick out any previous session.
"""
def process_request(self, request):
if request.user.is_authenticated():
try:
cur_session_key = request.user.get_profile().session_key
if cur_session_key and cur_session_key != request.session.session_key:
# Default handling... kick the old session...
Session.objects.get(session_key=cur_session_key).delete()
if not cur_session_key or cur_session_key != request.session.session_key:
p = request.user.get_profile()
p.session_key = request.session.session_key
p.save()
except ObjectDoesNotExist:
pass
Tak daleko, tak dobrze ... na serwer dev Django (serwer zarządzający manage.py) wszystko działa poprawnie, kopie starą sesję ...
... ale przy użyciu Apache (z mod_wsgi), to nie działa!
Starałem się znaleźć żadnych informacji na ten temat, ale nie ma szczęścia do tej pory ...
Najbliższy znalazłem jest this, ale to niby „przeciwnym” problem ...
Każda pomoc będzie bardzo ceniona.
Edit: dodałem wydruk debugowania przed usunięciem Session ... oto fragment z error.log Apache:
[Fri Jan 20 09:56:50 2012] [error] old key = f42885ccb7f33b6afcb2c18fca14f44a
[Fri Jan 20 09:56:50 2012] [error] new key = ce4cfb672e6025edb8ffcd0cf2b4b8d1
[Fri Jan 20 09:57:14 2012] [error] old key = f42885ccb7f33b6afcb2c18fca14f44a
[Fri Jan 20 09:57:14 2012] [error] new key = 0815c56241ac21cf4b14b326f0aa7e24
pierwsze dwa kłamstwa są od kiedy wszedł do pierwszej sesji (Firefox)
dwa ostatnie są od kiedy wszedłem z drugiej sesji (chrom)
... okazuje się, że stary zapis sesji nie zostaną usunięte ... ???
biegnę w porównaniu z dokładnie tej samej instancji PostgreSQL jak ja z devserver ...
Edit2: Okazało się, że mój kod był buggy ... to nie udało, gdy nowy Session_key nie było znalezione w sesji ...
oto stały kod ... The try..except jest teraz w odpowiednim miejscu
class OnlyOneUserMiddleware(object):
"""
Middleware to ensure that a logged-in user only has one session active.
Will kick out any previous session.
"""
def process_request(self, request):
if request.user.is_authenticated():
cur_session_key = request.user.get_profile().session_key
if cur_session_key and cur_session_key != request.session.session_key:
# Default handling... kick the old session...
try:
s = Session.objects.get(session_key=cur_session_key)
s.delete()
except ObjectDoesNotExist:
pass
if not cur_session_key or cur_session_key != request.session.session_key:
p = request.user.get_profile()
p.session_key = request.session.session_key
p.save()
Kiedy mówisz "nie działa", co dokładnie nie działa? Wciąż widzisz starą sesję w DB? Jeśli umieścisz wywołanie drukowania/rejestrowania tuż przed usunięciem 'Session', czy widzisz, że zostało wykonane w' mod_wsgi'? – AdamKG
@AdamKG: Dzięki za wskazanie mnie we właściwym kierunku! –
Jeśli silnik sesji to cache_db, myślę, że musimy również ręcznie usunąć sessionkey z pamięci podręcznej, prawda? – Wesley