I'm writing a User system that cannot login at the same time.
If the account in login state in somewhere, and someone login the same account in other position. The latter one will be logged in. And the previous will be logged out.
I'm using a model with oneToOneField associated to the User model, And save session ids of this user.
The code is like below.
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from .myModels import JSONField
class Profile(models.Model):
user = models.OneToOneField(User, models.CASCADE)
sessionids = JSONField(null=True)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
The JSONField is a field that using textField to store JSON string.
When a user login, I go to get all session ids of this user and delete all the session ids. Then I add current session id to the Profile. By doing this, I can logout in the previous position. the code is like below.
def login(request):
if request.method == "POST":
if request.user.is_authenticated:
return HttpResponse("the user session is authenticated.")
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None and user.is_active:
auth.login(request, user)
#remove cur user all sessions
sessionidsToDelete = request.user.profile.sessionids
if sessionidsToDelete != None:
sessions = Session.objects.filter(session_key__in=sessionidsToDelete)
for session in sessions:
session.delete()
#add cur user sessions
sessionidsToStore = user.profile.sessionids
print("sessionidsToStore = ")
print(sessionidsToStore)
print("sessionidsToDelete = ")
print(sessionidsToDelete)
if sessionidsToStore== None:
sessionidsToStore = []
else:
sessionidsToStore = list(set(sessionidsToStore) - set(sessionidsToDelete))
print("sessionidsToStore = ")
print(sessionidsToStore)
sessionidsToStore.append(request.session.session_key)
user.profile.sessionids = json.dumps(sessionidsToStore)
user.profile.save()
rotate_token(request)
return HttpResponse("login sucessful")
elif user.is_active == False:
userNotActivedHttpresponse = HttpResponse()
userNotActivedHttpresponse.status_code = 605
userNotActivedHttpresponse.reason_phrase = "This user not active"
return userNotActivedHttpresponse
else:
return HttpResponse("Please Input the correct username and password")
else:
return HttpResponseBadRequest("Please use POST to login")
But I think something will happen. When there two people want to login the same account at the same time.
For example, there are two people know the same account.
They login at the same time. It may be happen that B append B's session id to Profile after A remove all other session ids. In this situation, A and B will still in login state, and won't be logout. How could I prevent this problem?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…