Django 2.1.7获取会话密钥

时间:2019-02-13 11:29:51

标签: python django session

我知道这可能是重复的帖子,为此我找到了解决方案,但是这些帖子来自旧版本的Django,我无法获得新的语法。有人可以给我小费吗?

我正试图阻止用户同时使用同一帐户。因此,当某人登录一个帐户时,如果用户和密码都可以,我将遍历django_session表,以查找是否有其他具有相同帐户的会话,如果是,请关闭该会话并开始最后一个会话。 / p>

经过auth.authenticate(blah blah):

    if user is not None:
                # Checks if there's any other active session with the same account
                for session in Session.objects.filter(session_key=request.session.session_key): # //aq
                    data = session.get_decoded()
                    print(data.get('_auth_user_id', None))
                    if data.get('_auth_user_id', None) == str(user.id):
                    session.delete()

但是这种语法不能正常工作。 我无法获取会话用户的ID。 当用户登录时,我正在使用request.session['logueado'] = user.idauth.login(request, user)

这应该类似于“最后一次登录获胜”系统。

编辑:整个代码:

def login(request):
    if 'logged' in request.session:
        return redirect(main)
    if request.method == "GET":
        form = LoginForm
        return render(request, "login.html", {"form": form})
    if request.method == "POST":
        print('POST method.')
        form = LoginForm(request.POST)
        if form.is_valid():
            print('Valid form.')
            user_name = form.cleaned_data.get('username')
            user_pass = form.cleaned_data.get('password')
            user = auth.authenticate(username=user_name, password=user_pass)
            if user is not None:
                for session in Session.objects.filter(session_key=request.session.session_key):
                    print('Hello')
                    data = session.get_decoded()
                    if data.get('_auth_user_id', None) == request.session.session_key:
                        print('Same account in more than 1 session.')
                        session.delete()
                #------------------------------------------------------------------
                request.session['logged'] = user.id
                print(request.session['logged'])
                auth.login(request, user)
                request.session.set_expiry(0) #
                return redirect(main)
            else:
                return render(request, "loginError.html", {"form": form})

编辑:最终解决方案:(谢谢丹尼尔·罗斯曼!)

user = auth.authenticate(username=user_name, password=user_pass)
if user is not None:
    # Checks if there's another session with the same acc
    Sessions = Session.objects.all()
    for row in Sessions:
        print(row.get_decoded().get('_auth_user_id'))
            print(user.id)
            if str(row.get_decoded().get("_auth_user_id")) == str(user.id):
                print('Same sessions')
                row.delete()

    request.session['logged'] = user.id

2 个答案:

答案 0 :(得分:1)

您的代码基于各种错误的假设。

会话密钥不以任何方式映射到登录ID。而且它们是唯一的:即使每个客户端以同一用户身份登录,每个客户端也将具有不同的密钥。而且,当用户登录时,会话将被明确刷新,因此他们将获得一个新密钥。

换句话说,执行此操作的唯一方法是遍历数据库中的所有所有会话,对其进行解码,然后检查其_auth_user_id项是否等于用户ID。

答案 1 :(得分:0)

正如Daniel Roseman回答的那样,您可以遍历数据库中的所有所有会话,对所有会话进行解码,然后删除所需的会话。但这很慢,尤其是在您的网站流量高且会话很多的情况下。

如果您需要更快的解决方案,则可以使用会话后端,该后端可让您查询并获取特定用户的会话。在这些会话后端中,会话具有用户的外键,因此您无需遍历所有会话对象:

使用这些后端,删除用户的所有会话可以在一行代码中完成:

newK = 1*4 + 1 = 5

免责声明::我是var audio = document.createElement('audio'); audio.src = "https://s3-eu-west-1.amazonaws.com/hitzmania/Xin8nXIPz4YH"; document.getElementById('play').addEventListener('click', function() { var promise = audio.play(); if (promise !== undefined) { promise.then(_ => {}).catch(error => { alert(error) }); } return false; })的作者。