[英]how to use custom model user in 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.