簡體   English   中英

將自定義用戶身份驗證添加到 django-rest-framework-simple-jwt

[英]Adding custom user authentication to django-rest-framework-simple-jwt

我想通過一次性密碼以及 django 中常用的用戶名/密碼方法添加用戶登錄。 為此,用戶名/密碼或用戶名/OTP 從客戶端發送到服務器,並且基於提供的字段對,如果用戶通過身份驗證,我需要返回訪問和刷新令牌。 我正在使用 django 的 simple-jwt。 我知道我必須重寫 TokenObtainPairView 和 TokenObtainSerializer。 問題是,我想自己做字段驗證部分。

在我看來,我覆蓋了 simple-jwt 的默認視圖。

#views.py

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

我重寫了如下的序列化程序:

#serializers.py

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):

    def validate(self, attrs):
        try:
            request = self.context["request"]
        except KeyError:
            pass

        try:
            request_data = json.loads(request.body)
            if("username" in request_data and "password" in request_data):
                # default scenario in simple-jwt  
                pass
            elif("username" in request_data and "otp" in request_data):                                   
                # validate username/otp manually and return access/token pair if successful
                pass

            else:
                # some fields were missing
                raise serializers.ValidationError({"username/otp or username/password" : "These fields are required"})

        except:
            pass

因此,如果客戶端在下面可能的 forms 之一中傳遞用戶憑據,我將能夠對其進行身份驗證並返回令牌對。

{
   "username" : "Winston",
   "password" : "testpass"
}

或者

{
    "username" : "Winston",
    "otp" : "testotp"
}

問題是,當我以第二種形式發送數據時,我得到400 BadRequest:password is required 如何自定義字段及其驗證?

正如Saiful Azad在評論中提到的,一種可能的方法是為每個場景使用單獨的序列化程序。

#views.py

class MyTokenObtainPairView(TokenObtainPairView):
    def get_serializer_class(self):
        if ("otp" in self.request.data):
            return MyTokenObtainPairSerializer
        return TokenObtainPairSerializer

然后,您可以實現自己的序列化程序進行 otp 驗證。 我使用simple-jwt 的實現來實現我自己的序列化程序並使用我的自定義身份驗證方法。

在你的urls.py

# Imports
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth.models import User
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny

@api_view(['GET'])
@permission_classes([AllowAny])
def get_tokens_for_user(request):

    # find the user base in params
    user = User.objects.first()

    refresh = RefreshToken.for_user(user)

    return Response({ 
       'refresh': str(refresh),
       'access': str(refresh.access_token),
    })

urlpatterns = [
    path('login', get_tokens_for_user, name="login")
]

暫無
暫無

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

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