由于session.backends已更改,对象无法JSON序列化

时间:2019-05-29 11:09:05

标签: django python-3.x session

我的网站通过用户可以在其个人资料页面上设置的PGP公钥使用2因子身份验证机制。 效果很好,但是由于我实施了单会话策略,因此我在这里找到了:How to prevent multiple login in Django <-我的2FA页面返回

  

PGPMessage类型的对象不可JSON序列化

这种行为在我更改后立即出现:

SESSION_ENGINE = "django.contrib.sessions.backends.cache"

SESSION_ENGINE = "django.contrib.sessions.backends.db"

在settings.py。因此,我想我只是无法正确处理会话,但是为什么我能够从缓存中获取所有需要的数据,而不是从settings.py中配置的数据库中获取所有必需的数据呢?

models.py

class UserSession(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    session = models.OneToOneField(Session, on_delete=models.CASCADE)

signals.py

from django.contrib.auth import user_logged_in
from django.contrib.sessions.models import Session
from django.dispatch.dispatcher import receiver
from .models import UserSession


@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=Session.objects.get(pk=request.session.session_key)
    )

views.py

def 2fa(request):
    if request.method == 'POST':
        form = Login2faForm(request.POST)
        if form.is_valid():
            if request.POST['token'] == request.session['token']:
                user = User.objects.get(id=request.session['userID'])
                hybridlogin(request, user)
                return redirect(reverse('home'))
            else:
                encrypted_token_message = request.session['encrypted_token']
                messages.error(request, 'Wrong Login Code, Please try again.')
                return render(request, 'Accounts/2fa.html', {'form': Login2faForm(), 'token': str(encrypted_token_message)}
                              )
        else:
            encrypted_token_message = request.session['encrypted_token']
            messages.error(request, 'Wrong Login Code, Please try again.')
            return render(request, 'Accounts/2fa.html', {'form': Login2faForm(), 'token': str(encrypted_token_message)})
    else:
        token = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(30))
        token_message = token
        if 'token' not in request.session:
            request.session['token'] = token
            user = User.objects.get(id=request.session['userID'])
        if 'encrypted_token' not in request.session:
            encryption_key = PGPKey.from_blob(user.pubpgp.rstrip("\r\n"))[0]
            encrypted_token_message = encryption_key.encrypt(PGPMessage.new(token_message), cipher=SymmetricKeyAlgorithm.AES256)
            request.session['encrypted_token'] = encrypted_token_message
        else:
            encrypted_token_message = request.session['encrypted_token']
        return render(request, 'Accounts/2fa.html', {'form': Login2faForm(), 'token': str(encrypted_token_message)})

由于我将会话后端更改为数据库,以便单一登录策略正常工作,所以我猜以下行得到错误处理:

user = User.objects.get(id=request.session['userID'])

0 个答案:

没有答案