web-dev-qa-db-ja.com

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

したがって、クライアントが以下の可能な形式のいずれかでユーザーの資格情報を渡すと、それを認証してトークンのペアを返すことができます。

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

または

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

問題は、2番目の形式でデータを送信すると、400 BadRequest:password is required。フィールドとその検証をカスタマイズするにはどうすればよいですか?

3
Winston

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の実装 を使用して独自のシリアライザを実装し、カスタム認証方法を使用しました。

1
Winston