Skip to content

Instantly share code, notes, and snippets.

@fleepgeek
Last active September 10, 2024 20:50
Show Gist options
  • Save fleepgeek/92b01d3187cf92b4495d71c69ee818df to your computer and use it in GitHub Desktop.
Save fleepgeek/92b01d3187cf92b4495d71c69ee818df to your computer and use it in GitHub Desktop.
A Django Middleware to prevent multiple sessions for the same user. It automatically logs out the previous session and replaces it with the new session.
from django.apps import AppConfig
class ForumConfig(AppConfig):
name = 'forum'
# This function is the only new thing in this file
# it just imports the signal file when the app is ready
def ready(self):
import your_app_name.signals
# Remember to add it in the MIDDLEWARE array in the settings.py file
# like so: 'your_app_name.middleware.OneSessionPerUserMiddleware'
from django.contrib.sessions.models import Session
class OneSessionPerUserMiddleware:
# Called only once when the web server starts
def __init__(self, get_response):
self.get_response = get_response
# Called once per request
def __call__(self, request):
# This codition is required because anonymous users
# dont have access to 'logged_in_user'
if request.user.is_authenticated:
# Gets the user's session_key from the database
current_session_key = request.user.logged_in_user.session_key
# If the session_key exists in the db and it is different from the browser's session
if current_session_key and current_session_key != request.session.session_key:
Session.objects.get(session_key=current_session_key).delete()
# Update the user's session_key in the db
request.user.logged_in_user.session_key = request.session.session_key
request.user.logged_in_user.save()
response = self.get_response(request)
return response
# Model to store the list of logged in users
class LoggedInUser(models.Model):
user = models.OneToOneField(User, related_name='logged_in_user')
# Session keys are 32 characters long
session_key = models.CharField(max_length=32, null=True, blank=True)
def __str__(self):
return self.user.username
# Signals that fires when a user logs in and logs out
from django.contrib.auth import user_logged_in, user_logged_out
from django.dispatch import receiver
from your_app_name.models import LoggedInUser
@receiver(user_logged_in)
def on_user_logged_in(sender, request, **kwargs):
LoggedInUser.objects.get_or_create(user=kwargs.get('user'))
@receiver(user_logged_out)
def on_user_logged_out(sender, **kwargs):
LoggedInUser.objects.filter(user=kwargs.get('user')).delete()
@fleepgeek
Copy link
Author

You're welcome.

@georgiawang5332
Copy link

Thank you for your offer. I made it
--- 04/21/2021

@fleepgeek
Copy link
Author

That's nice.
I'm glad you found it helpful.

@thiagolara
Copy link

Great, it works very well ! 🚀

@hasala1996
Copy link

Hola, cómo funcionaría esto con jwt? lo he implementado y pues siempre obtengo UsuarioAnonimo, porque obviamente estoy usando otro sistema de autenticacion por token.

@oleglpts
Copy link

Thanks, that's very nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment