簡體   English   中英

驗證用戶帳戶是否在 Django Rest Framework 中處於活動狀態

[英]Validate if user account is active in Django Rest Framework

我正在嘗試通過電子郵件鏈接實現帳戶激活。 我的User模型很簡單,繼承自django.contrib.auth.models.AbstractUser ,所以它默認有is_active字段。 注冊后,使用is_active=False參數創建新用戶,我想處理案例,當用戶嘗試登錄時,即使憑據很好,也不應該登錄,因為帳戶未激活。 我正在使用 Knox 令牌身份驗證。 我的序列化器:

from django.contrib.auth import authenticate
from rest_framework import serializers, exceptions


class LoginUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserModel
        fields = ('username', 'password')

    def validate(self, data):
        user = authenticate(**data)
        if user:
            if user.is_active:
                return user
            raise exceptions.AuthenticationFailed('Account is not activated')
        raise exceptions.AuthenticationFailed()

並查看:

from django.contrib.auth import login
from rest_framework.permissions import AllowAny
from rest_framework.authtoken.serializers import AuthTokenSerializer
from knox.views import LoginView
from .serializers import LoginUserSerializer


class LoginUserView(LoginView):
    serializer_class = LoginUserSerializer
    permission_classes = [AllowAny]

    def post(self, request, *args, **kwargs):
        serializer = AuthTokenSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)
        return super(LoginUserView, self).post(request)

使用該代碼,我偶然發現了問題:當我嘗試使用已激活的帳戶登錄時,一切看起來都很好,但是當我嘗試未激活的帳戶時,而不是Account is not activated ,我得到:

{
    "non_field_errors": [
        "Unable to log in with provided credentials."
    ]
}

我認為,與其說是序列化程序,不如說是來自視圖。

好的,多虧了 Shafikur Ra​​hman 的建議,我才能讓它發揮作用。 在我嘗試使用pdb調試它並在LoginUserSerializer設置跟蹤但沒有發生任何事情后,我意識到在我的視圖中我不是指向我編寫的序列化程序,而是指向AuthTokenSerializer 即使在那之后它仍然不起作用,因為我對 django login()和 DRF validate()工作原理缺乏了解。 以下固定代碼供參考:

看法:

class LoginUserView(LoginView):
    serializer_class = LoginUserSerializer
    permission_classes = [AllowAny]

    def post(self, request, *args, **kwargs):
        serializer = LoginUserSerializer(data=request.data)  # changed  to desired serializer
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)
        return super(LoginUserView, self).post(request)

和序列化器:

class LoginUserSerializer(serializers.ModelSerializer):
    username = serializers.CharField()  # added missing fields for serializer
    password = serializers.CharField()

    class Meta:
        model = UserModel
        fields = ('username', 'password')

    def validate(self, data):
        user = authenticate(**data)
        if user:
            if user.is_active:
                data['user'] = user  # added user model to OrderedDict that serializer is validating
                return data  # and in sunny day scenario, return this dict, as everything is fine
            raise exceptions.AuthenticationFailed('Account is not activated')
        raise exceptions.AuthenticationFailed()

此外,為了能夠對非活動用戶進行authenticate() ,我必須添加

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.AllowAllUsersModelBackend'
]

在項目設置中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM