gpt4 book ai didi

django - 如何防止在Django中多次登录

转载 作者:行者123 更新时间:2023-12-03 13:48:22 26 4
gpt4 key购买 nike

我正在编写一个无法同时登录的用户系统。
如果帐户在某处处于登录状态,而有人在其他位置登录同一帐户。后一个将被登录。前一个将被注销。
我正在使用与用户模型关联的 oneToOneField 模型,并保存该用户的 session ID。
代码如下所示。

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)

JSONField 是一个使用 textField 来存储 JSON 字符串的字段。
当用户登录时,我会获取该用户的所有 session ID 并删除所有 session ID。然后我将当前 session ID 添加到配置文件中。通过这样做,我可以在以前的位置注销。代码如下。
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")

但我认为会发生一些事情。当有两个人想同时登录同一个帐户时。
例如,有两个人知道同一个帐户。
他们同时登录。在 A 删除所有其他 session id 之后,B 可能会将 B 的 session id 附加到 Profile 中。在这种情况下,A 和 B 仍然处于登录状态,不会退出。我怎样才能防止这个问题?

最佳答案

我认为您通过将数据存储在 UserProfile 中使事情变得非常复杂s, etc. 然后有信号,你引入了很多关卡,在每个关卡,事情都可能出错。
这里我们基本上需要两件事:一个映射 User 的表。 s 到相应的设置。我们可以用 UserSession 来实现它。模型:

# models.py

from django.conf import settings
from django.db import models
from django.contrib.sessions.models import Session

class UserSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
session = models.OneToOneField(Session, on_delete=models.CASCADE)
所以 UserSession对象在 User 之间建立链接和 Session s。现在我们可以实现一个登录钩子(Hook):一个在用户登录时触发的信号。在这种情况下,我们执行两件事:
  • 我们删除所有 Session UserSession 的 s(和相应的 User s)活跃的;和
  • 我们创建一个新的Session和相应的UserSession我们可以稍后删除。喜欢:
  • from django.contrib.auth import user_logged_in
    from django.dispatch.dispatcher import receiver

    @receiver(user_logged_in)
    def remove_other_sessions(sender, user, request, **kwargs):
    # remove other sessions
    Session.objects.filter(usersession__user=user).delete()

    # save current session
    request.session.save()

    # create a link from the user to the current session (for later removal)
    UserSession.objects.get_or_create(
    user=user,
    session_id=request.session.session_key
    )

    关于django - 如何防止在Django中多次登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50833980/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com