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
したがって、クライアントが以下の可能な形式のいずれかでユーザーの資格情報を渡すと、それを認証してトークンのペアを返すことができます。
{
"username" : "Winston",
"password" : "testpass"
}
または
{
"username" : "Winston",
"otp" : "testotp"
}
問題は、2番目の形式でデータを送信すると、400 BadRequest:password is required
。フィールドとその検証をカスタマイズするにはどうすればよいですか?
Saiful Azad がコメントで述べられているように、1つの可能な方法は、シナリオごとに個別のシリアライザーを使用することです。
#views.py
class MyTokenObtainPairView(TokenObtainPairView):
def get_serializer_class(self):
if ("top" in self.request.data):
return MyTokenObtainPairSerializer
return TokenObtainPairSerializer
次に、OTP検証用に独自のシリアライザーを実装できます。私は simple-jwtの実装 を使用して独自のシリアライザを実装し、カスタム認証方法を使用しました。