Как решить ошибку 401 неавторизованный вход в DRF простой jwt вход пользователя

Я создаю DRF API аутентификации для пользователей Abstract Base в моем Django проекте и использую простой JWT. API регистрации и проверки электронной почты работают нормально, но когда я пытаюсь войти в систему, используя учетные данные действительного пользователя, я получаю ошибку 401 несанкционированный доступ.

пользовательская модель пользователя в models.py

class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=255, unique=True,db_index=True)
    email = models.EmailField(max_length=255, unique=True,db_index=True)
    is_verified = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELD = ['username']

    objects = UserManager()

    def __str__(self):
        return self.email

    def tokens(self):
        refresh = RefreshToken.for_user(self)
        return{
            'refresh':str(refresh),
            'access': str(refresh.access_token)
        }

Вот мое представление на основе класса логина в views.py:

class LoginAPIView(generics.GenericAPIView):
    serializer_class = LoginSerializer
    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        return Response(serializer.data, status=status.HTTP_200_OK)

Вот LoginSerializer в serializers.py

class LoginSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(max_length=255, min_length=3)
    password = serializers.CharField(max_length=68, min_length=8, write_only=True)
    username = serializers.CharField(max_length=255, min_length=3, read_only = True)
    tokens = serializers.CharField(max_length=68, min_length=8, read_only = True)


    class Meta:
        model = User
        fields = ['email', 'password', 'username', 'tokens']


    def validate(self, attrs):
        email = attrs.get('email', '')
        password = attrs.get('password', '')
  
        user = auth.authenticate(email=email, password=password)
        if not user:
            raise AuthenticationFailed('Invalid Credentials, try again!')

        if not user.is_active:
            raise AuthenticationFailed('Acccount disabled, please contact admin')

        if not user.is_verified:
            raise AuthenticationFailed('Email is not verified')
                

        return {
            'email': user.email,
            'username': user.username,
            'tokens': user.tokens

        }
        return super().validate(attrs)

В settings.py единственными настройками, имеющими отношение к DRF-simple Jwt, являются:

REST_FRAMEWORK = {
    'NON_FIELD_ERRORS_KEY': 'error',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

Выдается ошибка "Invalid credentials", означающая, что данные пользователя не существуют, в то время как пользователи на самом деле есть, когда я проверяю базу данных. enter image description here

Кто-нибудь, пожалуйста, помогите.

Вы хотите исключить представление входа в систему из проверки аутентификации в масштабах проекта, которую вы добавили в settings.py.

class LoginAPIView(generics.GenericAPIView):
    permission_classes = ()
    authentication_classes = ()
    serializer_class = LoginSerializer

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        return Response(serializer.data, status=status.HTTP_200_OK)

После долгих гуглений и головной боли, я в конце концов снова прочитал простую документацию по Jwt и, как оказалось, ошибка 401 возникает, если пользователь не активен. В моем models.py выше, по умолчанию, is_verified и is_active моего пользователя False. Представление VerifyEmail изменило is_verified на True после того, как пользователи подтвердили свою электронную почту, но их is_active остались False, выдавая ошибку 401. Моим решением было добавить is_active=True для случая, когда пользователь проверяет свой email: Вот VerifyEmail вид в views.py

class VerifyEmail(views.APIView):
    serializer_class = EmailVerificationSerializer

    token_param_config = openapi.Parameter('token',in_=openapi.IN_QUERY, description='Description', type=openapi.TYPE_STRING)

    @swagger_auto_schema(manual_parameters=[token_param_config])
    def get(self, request):
        token = request.GET.get('token')
        try:
            payload = jwt.decode(token,settings.SECRET_KEY, algorithms=['HS256'])
            user = User.objects.get(id=payload['user_id'])
            if not user.is_verified:
                user.is_verified = True
                user.is_active = True           # New
                user.save()
            return Response({'email': 'Succesfully activated'}, status = status.HTTP_200_OK)

        except jwt.ExpiredSignatureError as identifier:
            return Response({'error': 'Activation Expired'}, status= status.HTTP_400_BAD_REQUEST)
        except jwt.exceptions.DecodeError as identifier:
            return Response({'error': 'Invalid token'}, status=status.HTTP_400_BAD_REQUEST)

<
Вернуться на верх